prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

tags.go (3698B)


      1 package utils
      2 
      3 import (
      4 	"fmt"
      5 	"sort"
      6 	"strings"
      7 )
      8 
      9 // Tag is one colored label. Web and TUI both read this table, so a color
     10 // is changed here and nowhere else.
     11 type Tag struct {
     12 	Class   string
     13 	BG, FG  string
     14 	Aliases []string // lowercase labels that map to this tag
     15 }
     16 
     17 const (
     18 	dark  = "#0d0d0d"
     19 	light = "#ffffff"
     20 )
     21 
     22 // Brand colors where a brand exists; otherwise picked to stay distinct
     23 // from their neighbors in the same row.
     24 var Tags = []Tag{
     25 	// languages
     26 	{"lang-zig", "#f7a41d", dark, []string{"zig"}},
     27 	{"lang-rust", "#dea584", dark, []string{"rust"}},
     28 	{"lang-c", "#a8b9cc", dark, []string{"c"}},
     29 	{"lang-go", "#00add8", dark, []string{"go", "golang"}},
     30 	{"lang-ts", "#3178c6", light, []string{"typescript", "ts"}},
     31 	{"lang-python", "#ffd43b", dark, []string{"python"}},
     32 
     33 	// tools
     34 	{"tool-crux", "#2e5c9a", light, []string{"crux linux", "crux"}},
     35 	{"tool-helix", "#7f5ad6", light, []string{"helix"}},
     36 	{"tool-fish", "#2aa198", dark, []string{"fish"}},
     37 	{"tool-claude", "#d97757", dark, []string{"claude code", "claude"}},
     38 
     39 	// interests
     40 	{"interest-osdev", "#b4469b", light, []string{"osdev"}},
     41 	{"interest-firmware", "#2e8b57", light, []string{"firmware"}},
     42 	{"interest-tui", "#ffb000", dark, []string{"tui/cli tooling", "tui"}},
     43 	{"interest-unix", "#4c78a8", light, []string{"unix philosophy", "unix"}},
     44 	{"interest-webdev", "#2d7d9a", light, []string{"web development", "webdev"}},
     45 
     46 	// hobbies
     47 	{"hobby-audi", "#f2c400", dark, []string{"old-school audis"}},
     48 	{"hobby-rally", "#d7263d", light, []string{"rally"}},
     49 	{"hobby-soccer", "#2e9d5b", light, []string{"pickup soccer"}},
     50 
     51 	// project and experience tech
     52 	{"tech-cuda", "#76b900", dark, []string{"cuda"}},
     53 	{"tech-docker", "#2496ed", light, []string{"docker"}},
     54 	{"tech-kafka", "#e8e8e8", dark, []string{"kafka"}},
     55 	{"tech-rn", "#61dafb", dark, []string{"react native"}},
     56 	{"tech-supabase", "#3ecf8e", dark, []string{"supabase"}},
     57 	{"tech-rest", "#8b95a5", dark, []string{"rest"}},
     58 	{"tech-temporal", "#7c6cf2", light, []string{"temporal"}},
     59 	{"tech-pytorch", "#ee4c2c", light, []string{"pytorch"}},
     60 	{"tech-postgres", "#336791", light, []string{"postgresql", "postgres"}},
     61 	{"tech-astro", "#ff5d01", light, []string{"astro"}},
     62 	{"project-portfolio", "#b07a2f", dark, []string{"portfolio"}},
     63 }
     64 
     65 var tagByLabel = func() map[string]*Tag {
     66 	m := make(map[string]*Tag)
     67 	for i := range Tags {
     68 		for _, a := range Tags[i].Aliases {
     69 			m[a] = &Tags[i]
     70 		}
     71 	}
     72 	return m
     73 }()
     74 
     75 // LookupTag finds a tag by label, case-insensitively.
     76 func LookupTag(label string) (Tag, bool) {
     77 	t, ok := tagByLabel[strings.ToLower(strings.TrimSpace(label))]
     78 	if !ok {
     79 		return Tag{}, false
     80 	}
     81 	return *t, true
     82 }
     83 
     84 // TagClass returns the CSS class for a label, or "" for the default style.
     85 func TagClass(label string) string {
     86 	t, _ := LookupTag(label)
     87 	return t.Class
     88 }
     89 
     90 // TagColor returns the background color for a label, or "" if untagged.
     91 func TagColor(label string) string {
     92 	t, _ := LookupTag(label)
     93 	return t.BG
     94 }
     95 
     96 // TagCSS renders one rule per tag for the web stylesheet.
     97 func TagCSS() string {
     98 	rules := make([]string, 0, len(Tags))
     99 	for _, t := range Tags {
    100 		rules = append(rules, fmt.Sprintf(".tag.%s{background:%s;color:%s}", t.Class, t.BG, t.FG))
    101 	}
    102 	sort.Strings(rules)
    103 	return strings.Join(rules, "\n")
    104 }
    105 
    106 var techAbbreviations = map[string]string{
    107 	"typescript": "TS",
    108 }
    109 
    110 // TechMeta is the short "rust, cuda" line shown in the project list.
    111 func TechMeta(tech []string) string {
    112 	parts := make([]string, 0, 2)
    113 	for _, item := range tech {
    114 		if len(parts) == 2 {
    115 			break
    116 		}
    117 		if short, ok := techAbbreviations[strings.ToLower(item)]; ok {
    118 			item = short
    119 		}
    120 		parts = append(parts, item)
    121 	}
    122 	return strings.Join(parts, ", ")
    123 }