macOS client store and API
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
property = regexp.MustCompile(`^\s*--([a-z0-9-]+):\s*#([0-9a-f]{6});\s*$`)
|
||||
darkOpen = regexp.MustCompile(`^@media \(prefers-color-scheme: dark\) \{$`)
|
||||
)
|
||||
|
||||
func block(lines []string, start int) (map[string]string, []string) {
|
||||
colors := map[string]string{}
|
||||
order := []string{}
|
||||
for _, line := range lines[start+1:] {
|
||||
if strings.TrimSpace(line) == "}" {
|
||||
return colors, order
|
||||
}
|
||||
m := property.FindStringSubmatch(line)
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
colors[m[1]] = m[2]
|
||||
order = append(order, m[1])
|
||||
}
|
||||
log.Fatalf("unterminated block at line %d", start+1)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func swiftName(prop string) string {
|
||||
parts := strings.Split(prop, "-")
|
||||
for i := 1; i < len(parts); i++ {
|
||||
parts[i] = strings.ToUpper(parts[i][:1]) + parts[i][1:]
|
||||
}
|
||||
return strings.Join(parts, "")
|
||||
}
|
||||
|
||||
func main() {
|
||||
css, err := os.ReadFile("../web/style.css")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
lines := strings.Split(string(css), "\n")
|
||||
lightAt, darkAt := -1, -1
|
||||
for i, line := range lines {
|
||||
if line == ":root {" && lightAt < 0 {
|
||||
lightAt = i
|
||||
}
|
||||
if darkOpen.MatchString(line) && i+1 < len(lines) && strings.TrimSpace(lines[i+1]) == ":root {" {
|
||||
darkAt = i + 1
|
||||
}
|
||||
}
|
||||
if lightAt < 0 || darkAt < 0 {
|
||||
log.Fatal("web/style.css has no :root block or no prefers-color-scheme: dark :root block")
|
||||
}
|
||||
light, order := block(lines, lightAt)
|
||||
dark, _ := block(lines, darkAt)
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString("// Code generated by go generate ./mac from web/style.css. DO NOT EDIT.\n\n")
|
||||
b.WriteString("import AppKit\nimport SwiftUI\n\n")
|
||||
b.WriteString("enum Palette {\n")
|
||||
for _, prop := range order {
|
||||
d, ok := dark[prop]
|
||||
if !ok {
|
||||
log.Fatalf("--%s has no dark value", prop)
|
||||
}
|
||||
fmt.Fprintf(&b, " static let %s = dynamic(0x%s, 0x%s)\n", swiftName(prop), light[prop], d)
|
||||
}
|
||||
for prop := range dark {
|
||||
if _, ok := light[prop]; !ok {
|
||||
log.Fatalf("--%s has no light value", prop)
|
||||
}
|
||||
}
|
||||
b.WriteString(`
|
||||
private static func rgb(_ hex: UInt32) -> NSColor {
|
||||
NSColor(srgbRed: CGFloat(hex >> 16 & 0xff) / 255, green: CGFloat(hex >> 8 & 0xff) / 255, blue: CGFloat(hex & 0xff) / 255, alpha: 1)
|
||||
}
|
||||
|
||||
private static func dynamic(_ light: UInt32, _ dark: UInt32) -> Color {
|
||||
Color(nsColor: NSColor(name: nil) { appearance in
|
||||
appearance.bestMatch(from: [.aqua, .darkAqua]) == .darkAqua ? rgb(dark) : rgb(light)
|
||||
})
|
||||
}
|
||||
}
|
||||
`)
|
||||
err = os.WriteFile("Sources/Byre/Palette.swift", []byte(b.String()), 0o644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user