// Capitalisation helpers for the free-text QSO fields (Name / QTH / Comment / // Note). // // The same station reaches the log SHOUTED by QRZ, lower-cased by a hurried // operator, and in whatever case the other logger stored it in an imported // ADIF — so one callsign ends up as "JEAN", "jean" and "Jean" across a log, // and sorting or reading a QTH column becomes a mess. // // Both helpers are meant to run on BLUR, never per keystroke: rewriting the // value while the operator is still typing a word fights them mid-word (see // the controlled-input note in CLAUDE.md). // titleCase upper-cases the first letter of every word and lower-cases the // rest. Separators are kept, so "SAINT-JULIEN" → "Saint-Julien" and // "o'brien" → "O'Brien". export function titleCase(s: string): string { return s .toLowerCase() .replace(/(^|[\s\-'’/.])(\p{L})/gu, (_m, sep: string, ch: string) => sep + ch.toUpperCase()); } // sentenceCase upper-cases the first letter and leaves everything after it as // typed. A comment routinely carries callsigns, modes and abbreviations // ("TNX QSO F5ABC, FT8 59") that lower-casing would quietly destroy — which is // why this is NOT titleCase. export function sentenceCase(s: string): string { return s.replace(/^(\s*)(\p{L})/u, (_m, sp: string, ch: string) => sp + ch.toUpperCase()); }