package render import "strings" // asciiMap is deliberately one rune to one ASCII character. // // Substitution happens after the table has been laid out, so anything that // changed the number of characters would shear every column to its right. That // constraint is why the wind arrows become single letters rather than the // two-letter compass points that would read better. var asciiMap = map[rune]string{ // Polish diacritics, so a Polish forecast survives GSM-7. 'ą': "a", 'ć': "c", 'ę': "e", 'ł': "l", 'ń': "n", 'ó': "o", 'ś': "s", 'ź': "z", 'ż': "z", 'Ą': "A", 'Ć': "C", 'Ę': "E", 'Ł': "L", 'Ń': "N", 'Ó': "O", 'Ś': "S", 'Ź': "Z", 'Ż': "Z", // Wind arrows. The arrow points the way the wind blows, so v is a northerly. '↑': "^", '↓': "v", '←': "<", '→': ">", '↖': "\\", '↗': "/", '↙': "/", '↘': "\\", // Chart: blocks and the axis rule. '█': "#", '▇': "#", '▆': "=", '▅': "=", '▄': "_", '▃': ":", '▂': ".", '▁': ".", '│': "|", } // ASCII rewrites output to pure ASCII, one character for one character. // // The point is SMS: a single non-ASCII character forces the whole message from // GSM-7 into UCS-2, which cuts a segment from 160 characters to 70. A degree // sign alone therefore more than doubles the cost of sending a forecast. // // The degree sign becomes the unit letter, which is both ASCII and clearer to // someone reading it cold: "29C" rather than "29". func ASCII(s, units string) string { degree := "C" if units == "imperial" { degree = "F" } runes := []rune(s) var b strings.Builder b.Grow(len(s)) for i, r := range runes { switch { case r == '°': // Prose from IMGW already writes "30°C"; appending the unit again // would give "30CC". Only a bare degree sign gains the letter. if i+1 < len(runes) && (runes[i+1] == 'C' || runes[i+1] == 'F') { continue } b.WriteString(degree) case r < 128: b.WriteRune(r) default: if sub, ok := asciiMap[r]; ok { b.WriteString(sub) } else { // Anything unmapped -- a place name in another script, a weather // code description we have not transliterated -- becomes '?' // rather than silently vanishing and misaligning the row. b.WriteString("?") } } } return b.String() }