// Package hu holds the Hungarian-locale formatting the server needs for share // metadata and share images. The browser keeps using Intl for everything it // renders itself; this exists because og: tags and PNGs are produced here. package hu import ( "strconv" "strings" "time" "unicode" ) // groupSeparator is U+00A0, which is what Intl.NumberFormat("hu-HU") emits. // A plain space here would make the share card disagree with the page. const groupSeparator = " " func FormatNumber(n int) string { s := strconv.Itoa(n) neg := strings.HasPrefix(s, "-") s = strings.TrimPrefix(s, "-") var b strings.Builder for i, r := range s { if i > 0 && (len(s)-i)%3 == 0 { b.WriteString(groupSeparator) } b.WriteRune(r) } if neg { return "-" + b.String() } return b.String() } // FormatHUF renders 1351600 as "1 351 600 Ft". func FormatHUF(n int) string { return FormatNumber(n) + " Ft" } func ProgressPct(raised, goal int) int { if goal <= 0 { return 0 } return int(float64(raised)/float64(goal)*100 + 0.5) } // DaysLeft counts whole days until the end of the closing day in Budapest — // SPEC.md section 6. Never negative: a finished campaign has zero days left, // not a negative countdown. func DaysLeft(endsAt string, loc *time.Location, now time.Time) int { d, err := time.ParseInLocation("2006-01-02", endsAt, loc) if err != nil { return 0 } end := d.Add(24*time.Hour - time.Second) diff := end.Sub(now) if diff <= 0 { return 0 } days := int(diff / (24 * time.Hour)) if diff%(24*time.Hour) > 0 { days++ } return days } var accentFolds = map[rune]rune{ 'á': 'a', 'é': 'e', 'í': 'i', 'ó': 'o', 'ö': 'o', 'ő': 'o', 'ú': 'u', 'ü': 'u', 'ű': 'u', } // Slugify mirrors the browser-side helper so a slug the editor previews is the // slug that gets stored. func Slugify(input string) string { var b strings.Builder for _, r := range strings.ToLower(input) { if folded, ok := accentFolds[r]; ok { r = folded } if (r >= 'a' && r <= 'z') || unicode.IsDigit(r) { b.WriteRune(r) } else { b.WriteRune('-') } } slug := b.String() for strings.Contains(slug, "--") { slug = strings.ReplaceAll(slug, "--", "-") } slug = strings.Trim(slug, "-") if len(slug) > 80 { slug = strings.Trim(slug[:80], "-") } return slug }