golang.org/x/text@v0.14.0/language/examples_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package language_test 6 7 import ( 8 "fmt" 9 "net/http" 10 11 "golang.org/x/text/language" 12 ) 13 14 func ExampleCanonType() { 15 p := func(id string) { 16 fmt.Printf("Default(%s) -> %s\n", id, language.Make(id)) 17 fmt.Printf("BCP47(%s) -> %s\n", id, language.BCP47.Make(id)) 18 fmt.Printf("Macro(%s) -> %s\n", id, language.Macro.Make(id)) 19 fmt.Printf("All(%s) -> %s\n", id, language.All.Make(id)) 20 } 21 p("en-Latn") 22 p("sh") 23 p("zh-cmn") 24 p("bjd") 25 p("iw-Latn-fonipa-u-cu-usd") 26 // Output: 27 // Default(en-Latn) -> en-Latn 28 // BCP47(en-Latn) -> en 29 // Macro(en-Latn) -> en-Latn 30 // All(en-Latn) -> en 31 // Default(sh) -> sr-Latn 32 // BCP47(sh) -> sh 33 // Macro(sh) -> sh 34 // All(sh) -> sr-Latn 35 // Default(zh-cmn) -> cmn 36 // BCP47(zh-cmn) -> cmn 37 // Macro(zh-cmn) -> zh 38 // All(zh-cmn) -> zh 39 // Default(bjd) -> drl 40 // BCP47(bjd) -> drl 41 // Macro(bjd) -> bjd 42 // All(bjd) -> drl 43 // Default(iw-Latn-fonipa-u-cu-usd) -> he-Latn-fonipa-u-cu-usd 44 // BCP47(iw-Latn-fonipa-u-cu-usd) -> he-Latn-fonipa-u-cu-usd 45 // Macro(iw-Latn-fonipa-u-cu-usd) -> iw-Latn-fonipa-u-cu-usd 46 // All(iw-Latn-fonipa-u-cu-usd) -> he-Latn-fonipa-u-cu-usd 47 } 48 49 func ExampleTag_Base() { 50 fmt.Println(language.Make("und").Base()) 51 fmt.Println(language.Make("und-US").Base()) 52 fmt.Println(language.Make("und-NL").Base()) 53 fmt.Println(language.Make("und-419").Base()) // Latin America 54 fmt.Println(language.Make("und-ZZ").Base()) 55 // Output: 56 // en Low 57 // en High 58 // nl High 59 // es Low 60 // en Low 61 } 62 63 func ExampleTag_Script() { 64 en := language.Make("en") 65 sr := language.Make("sr") 66 sr_Latn := language.Make("sr_Latn") 67 fmt.Println(en.Script()) 68 fmt.Println(sr.Script()) 69 // Was a script explicitly specified? 70 _, c := sr.Script() 71 fmt.Println(c == language.Exact) 72 _, c = sr_Latn.Script() 73 fmt.Println(c == language.Exact) 74 // Output: 75 // Latn High 76 // Cyrl Low 77 // false 78 // true 79 } 80 81 func ExampleTag_Region() { 82 ru := language.Make("ru") 83 en := language.Make("en") 84 fmt.Println(ru.Region()) 85 fmt.Println(en.Region()) 86 // Output: 87 // RU Low 88 // US Low 89 } 90 91 func ExampleRegion_TLD() { 92 us := language.MustParseRegion("US") 93 gb := language.MustParseRegion("GB") 94 uk := language.MustParseRegion("UK") 95 bu := language.MustParseRegion("BU") 96 97 fmt.Println(us.TLD()) 98 fmt.Println(gb.TLD()) 99 fmt.Println(uk.TLD()) 100 fmt.Println(bu.TLD()) 101 102 fmt.Println(us.Canonicalize().TLD()) 103 fmt.Println(gb.Canonicalize().TLD()) 104 fmt.Println(uk.Canonicalize().TLD()) 105 fmt.Println(bu.Canonicalize().TLD()) 106 // Output: 107 // US <nil> 108 // UK <nil> 109 // UK <nil> 110 // ZZ language: region is not a valid ccTLD 111 // US <nil> 112 // UK <nil> 113 // UK <nil> 114 // MM <nil> 115 } 116 117 func ExampleCompose() { 118 nl, _ := language.ParseBase("nl") 119 us, _ := language.ParseRegion("US") 120 de := language.Make("de-1901-u-co-phonebk") 121 jp := language.Make("ja-JP") 122 fi := language.Make("fi-x-ing") 123 124 u, _ := language.ParseExtension("u-nu-arabic") 125 x, _ := language.ParseExtension("x-piglatin") 126 127 // Combine a base language and region. 128 fmt.Println(language.Compose(nl, us)) 129 // Combine a base language and extension. 130 fmt.Println(language.Compose(nl, x)) 131 // Replace the region. 132 fmt.Println(language.Compose(jp, us)) 133 // Combine several tags. 134 fmt.Println(language.Compose(us, nl, u)) 135 136 // Replace the base language of a tag. 137 fmt.Println(language.Compose(de, nl)) 138 fmt.Println(language.Compose(de, nl, u)) 139 // Remove the base language. 140 fmt.Println(language.Compose(de, language.Base{})) 141 // Remove all variants. 142 fmt.Println(language.Compose(de, []language.Variant{})) 143 // Remove all extensions. 144 fmt.Println(language.Compose(de, []language.Extension{})) 145 fmt.Println(language.Compose(fi, []language.Extension{})) 146 // Remove all variants and extensions. 147 fmt.Println(language.Compose(de.Raw())) 148 149 // An error is gobbled or returned if non-nil. 150 fmt.Println(language.Compose(language.ParseRegion("ZA"))) 151 fmt.Println(language.Compose(language.ParseRegion("HH"))) 152 153 // Compose uses the same Default canonicalization as Make. 154 fmt.Println(language.Compose(language.Raw.Parse("en-Latn-UK"))) 155 156 // Call compose on a different CanonType for different results. 157 fmt.Println(language.All.Compose(language.Raw.Parse("en-Latn-UK"))) 158 159 // Output: 160 // nl-US <nil> 161 // nl-x-piglatin <nil> 162 // ja-US <nil> 163 // nl-US-u-nu-arabic <nil> 164 // nl-1901-u-co-phonebk <nil> 165 // nl-1901-u-co-phonebk-nu-arabic <nil> 166 // und-1901-u-co-phonebk <nil> 167 // de-u-co-phonebk <nil> 168 // de-1901 <nil> 169 // fi <nil> 170 // de <nil> 171 // und-ZA <nil> 172 // und language: subtag "HH" is well-formed but unknown 173 // en-Latn-GB <nil> 174 // en-GB <nil> 175 } 176 177 func ExampleParse_errors() { 178 for _, s := range []string{"Foo", "Bar", "Foobar"} { 179 _, err := language.Parse(s) 180 if err != nil { 181 if inv, ok := err.(language.ValueError); ok { 182 fmt.Println(inv.Subtag()) 183 } else { 184 fmt.Println(s) 185 } 186 } 187 } 188 for _, s := range []string{"en", "aa-Uuuu", "AC", "ac-u"} { 189 _, err := language.Parse(s) 190 switch e := err.(type) { 191 case language.ValueError: 192 fmt.Printf("%s: culprit %q\n", s, e.Subtag()) 193 case nil: 194 // No error. 195 default: 196 // A syntax error. 197 fmt.Printf("%s: ill-formed\n", s) 198 } 199 } 200 // Output: 201 // foo 202 // Foobar 203 // aa-Uuuu: culprit "Uuuu" 204 // AC: culprit "ac" 205 // ac-u: ill-formed 206 } 207 208 func ExampleTag_Parent() { 209 p := func(tag string) { 210 fmt.Printf("parent(%v): %v\n", tag, language.Make(tag).Parent()) 211 } 212 p("zh-CN") 213 214 // Australian English inherits from World English. 215 p("en-AU") 216 217 // If the tag has a different maximized script from its parent, a tag with 218 // this maximized script is inserted. This allows different language tags 219 // which have the same base language and script in common to inherit from 220 // a common set of settings. 221 p("zh-HK") 222 223 // If the maximized script of the parent is not identical, CLDR will skip 224 // inheriting from it, as it means there will not be many entries in common 225 // and inheriting from it is nonsensical. 226 p("zh-Hant") 227 228 // The parent of a tag with variants and extensions is the tag with all 229 // variants and extensions removed. 230 p("de-1994-u-co-phonebk") 231 232 // Remove default script. 233 p("de-Latn-LU") 234 235 // Output: 236 // parent(zh-CN): zh 237 // parent(en-AU): en-001 238 // parent(zh-HK): zh-Hant 239 // parent(zh-Hant): und 240 // parent(de-1994-u-co-phonebk): de 241 // parent(de-Latn-LU): de 242 } 243 244 // ExampleMatcher_bestMatch gives some examples of getting the best match of 245 // a set of tags to any of the tags of given set. 246 func ExampleMatcher() { 247 // This is the set of tags from which we want to pick the best match. These 248 // can be, for example, the supported languages for some package. 249 tags := []language.Tag{ 250 language.English, // en 251 language.BritishEnglish, // en-GB 252 language.French, // fr 253 language.Afrikaans, // af 254 language.BrazilianPortuguese, // pt-BR 255 language.EuropeanPortuguese, // pt-PT 256 language.SimplifiedChinese, // zh-Hans 257 language.Raw.Make("iw-IL"), // Hebrew from Israel 258 language.Raw.Make("iw"), // Hebrew 259 language.Raw.Make("he"), // Hebrew 260 } 261 m := language.NewMatcher(tags) 262 263 // A simple match. 264 fmt.Println(m.Match(language.Make("fr"))) 265 266 // Australian English is closer to British English than American English. 267 // The resulting match is "en-GB-u-rg-auzzzz". The first language listed, 268 // "en-GB", is the matched language. Next is the region override prefix 269 // "-u-rg-", the region override "au", and the region override suffix "zzzz". 270 // The region override is for things like currency, dates, and measurement 271 // systems. 272 fmt.Println(m.Match(language.Make("en-AU"))) 273 274 // Default to the first tag passed to the Matcher if there is no match. 275 fmt.Println(m.Match(language.Make("ar"))) 276 277 // Get the default tag. 278 fmt.Println(m.Match()) 279 280 fmt.Println("----") 281 282 // We match SimplifiedChinese, but with Low confidence. 283 fmt.Println(m.Match(language.TraditionalChinese)) 284 285 // British English is closer to Australian English than Traditional Chinese 286 // to Simplified Chinese. 287 fmt.Println(m.Match(language.TraditionalChinese, language.Make("en-AU"))) 288 289 fmt.Println("----") 290 291 // In case a multiple variants of a language are available, the most spoken 292 // variant is typically returned. 293 fmt.Println(m.Match(language.Portuguese)) 294 295 // Pick the first value passed to Match in case of a tie. 296 fmt.Println(m.Match(language.Dutch, language.Make("fr-BE"), language.Make("af-NA"))) 297 fmt.Println(m.Match(language.Dutch, language.Make("af-NA"), language.Make("fr-BE"))) 298 299 fmt.Println("----") 300 301 // If a Matcher is initialized with a language and its deprecated version, 302 // it will distinguish between them. 303 fmt.Println(m.Match(language.Raw.Make("iw"))) 304 305 // However, for non-exact matches, it will treat deprecated versions as 306 // equivalent and consider other factors first. 307 fmt.Println(m.Match(language.Raw.Make("he-IL"))) 308 309 fmt.Println("----") 310 311 // User settings passed to the Unicode extension are ignored for matching 312 // and preserved in the returned tag. 313 fmt.Println(m.Match(language.Make("de-u-co-phonebk"), language.Make("fr-u-cu-frf"))) 314 315 // Even if the matching language is different. 316 fmt.Println(m.Match(language.Make("de-u-co-phonebk"), language.Make("br-u-cu-frf"))) 317 318 // If there is no matching language, the options of the first preferred tag are used. 319 fmt.Println(m.Match(language.Make("de-u-co-phonebk"))) 320 321 // Output: 322 // fr 2 Exact 323 // en-GB-u-rg-auzzzz 1 High 324 // en 0 No 325 // en 0 No 326 // ---- 327 // zh-Hans 6 Low 328 // en-GB-u-rg-auzzzz 1 High 329 // ---- 330 // pt-BR 4 Exact 331 // fr-u-rg-bezzzz 2 High 332 // af-u-rg-nazzzz 3 High 333 // ---- 334 // iw-IL 7 Exact 335 // he-u-rg-ilzzzz 9 Exact 336 // ---- 337 // fr-u-cu-frf 2 Exact 338 // fr-u-cu-frf 2 High 339 // en-u-co-phonebk 0 No 340 } 341 342 func ExampleMatchStrings() { 343 // languages supported by this service: 344 matcher := language.NewMatcher([]language.Tag{ 345 language.English, language.Dutch, language.German, 346 }) 347 348 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 349 lang, _ := r.Cookie("lang") 350 tag, _ := language.MatchStrings(matcher, lang.String(), r.Header.Get("Accept-Language")) 351 352 fmt.Println("User language:", tag) 353 }) 354 } 355 356 func ExampleComprehends() { 357 // Various levels of comprehensibility. 358 fmt.Println(language.Comprehends(language.English, language.English)) 359 fmt.Println(language.Comprehends(language.AmericanEnglish, language.BritishEnglish)) 360 361 // An explicit Und results in no match. 362 fmt.Println(language.Comprehends(language.English, language.Und)) 363 364 fmt.Println("----") 365 366 // There is usually no mutual comprehensibility between different scripts. 367 fmt.Println(language.Comprehends(language.Make("en-Dsrt"), language.English)) 368 369 // One exception is for Traditional versus Simplified Chinese, albeit with 370 // a low confidence. 371 fmt.Println(language.Comprehends(language.TraditionalChinese, language.SimplifiedChinese)) 372 373 fmt.Println("----") 374 375 // A Swiss German speaker will often understand High German. 376 fmt.Println(language.Comprehends(language.Make("gsw"), language.Make("de"))) 377 378 // The converse is not generally the case. 379 fmt.Println(language.Comprehends(language.Make("de"), language.Make("gsw"))) 380 381 // Output: 382 // Exact 383 // High 384 // No 385 // ---- 386 // No 387 // Low 388 // ---- 389 // High 390 // No 391 } 392 393 func ExampleTag_values() { 394 us := language.MustParseRegion("US") 395 en := language.MustParseBase("en") 396 397 lang, _, region := language.AmericanEnglish.Raw() 398 fmt.Println(lang == en, region == us) 399 400 lang, _, region = language.BritishEnglish.Raw() 401 fmt.Println(lang == en, region == us) 402 403 // Tags can be compared for exact equivalence using '=='. 404 en_us, _ := language.Compose(en, us) 405 fmt.Println(en_us == language.AmericanEnglish) 406 407 // Output: 408 // true true 409 // true false 410 // true 411 }