// Package i18n holds the translations for everything prognosis writes itself: // column headers, condition names, section labels, weekday and month names, and // pollen species and bands. // // What is deliberately NOT translated: the body of an IMGW warning. IMGW // publishes those in Polish only, and rendering an invented English version of // an official warning would be worse than showing the original. In English mode // the surrounding labels are English and the warning text stays Polish. package i18n import ( "fmt" "time" ) // Lang is a supported display language. type Lang string const ( EN Lang = "en" PL Lang = "pl" ) // Catalog is the set of strings for one language. type Catalog struct { lang Lang // Table headers, keyed by column name. headers map[string]string // WMO weather code descriptions. conditions map[int]string // Section labels and short words. words map[string]string // Pollen taxa. species map[string]string // Qualitative pollen levels. bands map[string]string weekdays [7]string months [12]string } var catalogs = map[Lang]*Catalog{EN: english(), PL: polish()} // For returns the catalogue for a language, falling back to English so a // mistyped language degrades to readable output rather than empty strings. func For(lang string) *Catalog { if c, ok := catalogs[Lang(lang)]; ok { return c } return catalogs[EN] } // Lang reports which language this catalogue is. func (c *Catalog) Lang() Lang { return c.lang } // Header is the column heading for a column name. func (c *Catalog) Header(column string) string { if s, ok := c.headers[column]; ok { return s } return column } // Condition describes a WMO weather code. Unknown codes are reported as such // rather than silently blank, so a new code in the API is visible. func (c *Catalog) Condition(code int) string { if s, ok := c.conditions[code]; ok { return s } return fmt.Sprintf("code %d", code) } // Word returns a label such as "day", "pollen" or "warnings". func (c *Catalog) Word(key string) string { if s, ok := c.words[key]; ok { return s } return key } // Species is the display name of a pollen taxon. func (c *Catalog) Species(name string) string { if s, ok := c.species[name]; ok { return s } return name } // Band is the display name of a qualitative pollen level. func (c *Catalog) Band(key string) string { if s, ok := c.bands[key]; ok { return s } return key } // Date formats a date as "Mon 10 Aug" in the catalogue's language. Go's time // package has no locale support, so the names come from the catalogue. func (c *Catalog) Date(t time.Time) string { return fmt.Sprintf("%s %02d %s", c.weekdays[int(t.Weekday())], t.Day(), c.months[int(t.Month())-1]) } func english() *Catalog { return &Catalog{ lang: EN, headers: map[string]string{ "hour": "hr", "icon": "", "temp": "temp", "feels": "feels", "conditions": "conditions", "mm": "mm", "rain": "rain", "wind": "wind", "gusts": "gusts", "dir": "dir", "humidity": "hum", "dew": "dew", "uv": "uv", "cloud": "cloud", "pressure": "hPa", "visibility": "vis", }, conditions: map[int]string{ 0: "clear", 1: "mainly clear", 2: "part cloudy", 3: "overcast", 45: "fog", 48: "rime fog", 51: "lt drizzle", 53: "drizzle", 55: "hvy drizzle", 56: "frz drizzle", 57: "frz drizzle", 61: "lt rain", 63: "rain", 65: "hvy rain", 66: "frz rain", 67: "frz rain", 71: "lt snow", 73: "snow", 75: "hvy snow", 77: "snow grains", 80: "lt showers", 81: "showers", 82: "hvy showers", 85: "snow showers", 86: "hvy snow showers", 95: "thunderstorm", 96: "storm + hail", 99: "storm + hail", }, words: map[string]string{ "sun": "sun", "up": "up", "down": "down", "day": "day", "dry": "dry", "pollen": "pollen", "rainfall": "rain", "over": "over", "daylight": "daylight", "of": "of", "max": "max", "level": "level", "warnings": "warnings", "could_not_check": "could not check IMGW", "poland_only": "IMGW covers Poland only", "hours_available": "hours available, not", "h_per_col": "h/col", "temp_row": "temp", "rain_row": "rain", }, species: map[string]string{ "grass": "grass", "birch": "birch", "alder": "alder", "mugwort": "mugwort", "ragweed": "ragweed", "olive": "olive", }, bands: map[string]string{ "none": "none", "low": "low", "medium": "medium", "high": "high", "very high": "very high", }, weekdays: [7]string{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, months: [12]string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}, } } func polish() *Catalog { return &Catalog{ lang: PL, headers: map[string]string{ "hour": "godz", "icon": "", "temp": "temp", "feels": "odczuw", "conditions": "warunki", "mm": "mm", "rain": "deszcz", "wind": "wiatr", "gusts": "porywy", "dir": "kier", "humidity": "wilg", "dew": "ros", "uv": "uv", "cloud": "chmury", "pressure": "hPa", "visibility": "wid", }, // Terminology follows IMGW's own vocabulary where it has one, so the // table and a warning describe the same weather in the same words. conditions: map[int]string{ 0: "bezchmurnie", 1: "gł. bezchmurnie", 2: "częśc. zachm.", 3: "zachmurzenie", 45: "mgła", 48: "mgła osadz.", 51: "słaba mżawka", 53: "mżawka", 55: "silna mżawka", 56: "mżawka marzn.", 57: "mżawka marzn.", 61: "słaby deszcz", 63: "deszcz", 65: "silny deszcz", 66: "deszcz marzn.", 67: "deszcz marzn.", 71: "słaby śnieg", 73: "śnieg", 75: "silny śnieg", 77: "ziarna śniegu", 80: "słabe przelotne", 81: "przelotne", 82: "silne przelotne", 85: "przelotny śnieg", 86: "silny przel. śnieg", 95: "burza", 96: "burza z gradem", 99: "burza z gradem", }, words: map[string]string{ "sun": "słońce", "up": "wsch", "down": "zach", "day": "dzień", "dry": "sucho", "pollen": "pyłek", "rainfall": "opad", "over": "przez", "daylight": "dnia", "of": "z", "max": "maks", "level": "stopień", "warnings": "ostrzeżenia", "could_not_check": "nie udało się sprawdzić IMGW", "poland_only": "IMGW obejmuje tylko Polskę", "hours_available": "godzin dostępnych, nie", "h_per_col": "h/kol", "temp_row": "temp", "rain_row": "opad", }, species: map[string]string{ "grass": "trawy", "birch": "brzoza", "alder": "olcha", "mugwort": "bylica", "ragweed": "ambrozja", "olive": "oliwka", }, bands: map[string]string{ "none": "brak", "low": "niskie", "medium": "średnie", "high": "wysokie", "very high": "b. wysokie", }, weekdays: [7]string{"nd", "pn", "wt", "śr", "cz", "pt", "sb"}, months: [12]string{"sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paź", "lis", "gru"}, } }