package format import ( "bytes" "fmt" "io" "os" "os/exec" "path/filepath" "strconv" "strings" "tomatentum.net/svg-templater/pkg/svg" ) type ConversionParameters struct { Format string Width, Height int } func ConvertByte(svgblob []byte, param ConversionParameters) ([]byte, error) { reader, err := ConvertReader(svgblob, param) if err != nil { return nil, err } defer reader.Close() result, err := io.ReadAll(reader) if err != nil { return nil, err } return result, nil } func ConvertReader(svgblob []byte, param ConversionParameters) (io.ReadCloser, error) { if param.Format == "svg" { return io.NopCloser(bytes.NewReader(svgblob)), nil } file, err := svg.CreateTemp(bytes.NewReader(svgblob), "svg") if err != nil { return nil, err } defer os.Remove(file) return runCommand(file, param) } func runCommand(input string, param ConversionParameters) (io.ReadCloser, error) { var args []string var outExt string switch param.Format { case "png": args = append(args, "--export-type=png") outExt = ".png" case "jpg": args = append(args, "--export-type=png") // inkscape doesn't export jpg directly outExt = ".png" case "pdf": args = append(args, "--export-type=pdf") outExt = ".pdf" default: return nil, fmt.Errorf("format not supported: %s", param.Format) } if param.Width > 0 { args = append(args, "-w", strconv.Itoa(param.Width)) } if param.Height > 0 { args = append(args, "-h", strconv.Itoa(param.Height)) } outFile := strings.TrimSuffix(input, filepath.Ext(input)) + outExt args = append(args, "-o", outFile) args = append(args, input) cmd := exec.Command("/opt/homebrew/bin/inkscape", args...) cmd.Dir = svg.TempDir out, err := cmd.CombinedOutput() if err != nil { return nil, fmt.Errorf("inkscape failed: %w: %s", err, string(out)) } file, err := os.Open(outFile) if err != nil { return nil, err } return file, nil } func CheckInkscape() bool { _, err := exec.LookPath("inkscape") return err == nil }