package dunst import ( "Sithego/themer" "os" "path/filepath" "regexp" "strconv" "strings" "text/template" ) type Adapter struct { OutputDir string } type Option func(*Adapter) func WithOutputDir(dir string) Option { return func(a *Adapter) { a.OutputDir = dir } } func New(opt ...Option) *Adapter { home, _ := os.UserHomeDir() a := &Adapter{ OutputDir: filepath.Join(home, ".config", "dunst"), } for _, o := range opt { o(a) } return a } func (a *Adapter) Name() string { return "Dunst" } type tmplData struct { Theme themer.Theme Padding struct { V int H int } Radius struct { Small int Base int Large int } } func (a *Adapter) Generate(t themer.Theme) error { templatePath := filepath.Join("themer", "adapters", "dunst", "dunstrc") templ, err := template.ParseFiles(templatePath) if err != nil { return err } if err := os.MkdirAll(a.OutputDir, 0o755); err != nil { return err } outputPath := filepath.Join(a.OutputDir, "dunstrc") f, err := os.Create(outputPath) if err != nil { return err } defer f.Close() data := tmplData{Theme: t} vp, hp := parsePaddingPair(t.Spacing.Padding) data.Padding.V = vp data.Padding.H = hp data.Radius.Small = parsePx(t.Spacing.RadiusSmall) if data.Radius.Small == 0 { data.Radius.Small = 4 } data.Radius.Base = parsePx(t.Spacing.Radius) if data.Radius.Base == 0 { data.Radius.Base = data.Radius.Small } data.Radius.Large = parsePx(t.Spacing.RadiusLarge) if data.Radius.Large == 0 { data.Radius.Base = data.Radius.Large } if err := templ.Execute(f, data); err != nil { return err } return nil } var rePxPair = regexp.MustCompile(`(?i)\b(\d+)\s*px\b(?:\s+(\d+)\s*px\b)?`) var rePx = regexp.MustCompile(`(?i)\b(\d+)\s*px\b`) func parsePaddingPair(s string) (int, int) { s = strings.TrimSpace(s) if s == "" { return 0, 0 } m := rePxPair.FindStringSubmatch(s) if len(m) == 3 { v, _ := strconv.Atoi(m[1]) if m[2] != "" { h, _ := strconv.Atoi(m[2]) return v, h } // single value provided -> use for both return v, v } // fallback: try generic px m2 := rePx.FindStringSubmatch(s) if len(m2) == 2 { v, _ := strconv.Atoi(m2[1]) return v, v } return 0, 0 } func parsePx(s string) int { s = strings.TrimSpace(s) m := rePx.FindStringSubmatch(s) if len(m) == 2 { v, _ := strconv.Atoi(m[1]) return v } return 0 }