language: simplify docs Most use cases will be limited to the given examples. It now refers to the blog for more details. Removed section on rolling your own locale-specific service as it added too much overhead to the doc, should be rare and also the example did not apply to all cases. Change-Id: I9db582c447d2a707ff83ee0752ef4ceb97306b2c Reviewed-on: https://go-review.googlesource.com/59814 Run-TryBot: Marcel van Lohuizen <mpvl@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/language/doc.go b/language/doc.go index 6dcbbe0..8afecd5 100644 --- a/language/doc.go +++ b/language/doc.go
@@ -4,84 +4,83 @@ // Package language implements BCP 47 language tags and related functionality. // -// The Tag type, which is used to represent languages, is agnostic to the -// meaning of its subtags. Tags are not fully canonicalized to preserve -// information that may be valuable in certain contexts. As a consequence, two -// different tags may represent identical languages. +// The most important function of package language is to match a list of +// user-preferred languages to a list of supported languages. +// It alleviates the developer of dealing with the complexity of this process +// and provides the user with the best experience +// (see https://blog.golang.org/matchlang). // -// Initializing language- or locale-specific components usually consists of -// two steps. The first step is to select a display language based on the -// preferred languages of the user and the languages supported by an application. -// The second step is to create the language-specific services based on -// this selection. Each is discussed in more details below. // // Matching preferred against supported languages // -// An application may support various languages. This list is typically limited -// by the languages for which there exists translations of the user interface. -// Similarly, a user may provide a list of preferred languages which is limited -// by the languages understood by this user. -// An application should use a Matcher to find the best supported language based -// on the user's preferred list. -// Matchers are aware of the intricacies of equivalence between languages. -// The default Matcher implementation takes into account things such as -// deprecated subtags, legacy tags, and mutual intelligibility between scripts -// and languages. +// A Matcher for an application that supports English, Australian English, +// Danish, and standard Mandarin can be created as follows: // -// A Matcher for English, Australian English, Danish, and standard Mandarin can -// be defined as follows: +// var matcher = language.NewMatcher([]language.Tag{ +// language.English, // The first language is used as fallback. +// language.MustParse("en-AU"), +// language.Danish, +// language.Chinese, +// }) // -// var matcher = language.NewMatcher([]language.Tag{ -// language.English, // The first language is used as fallback. -// language.MustParse("en-AU"), -// language.Danish, -// language.Chinese, -// }) +// This list of supported languages is typically implied by the languages for +// which there exists translations of the user interface. // -// The following code selects the best match for someone speaking Spanish and -// Norwegian: +// User-preferred languages usually come as a comma-separated list of BCP 47 +// language tags. +// The MatchString finds best matches for such strings: // -// preferred := []language.Tag{ language.Spanish, language.Norwegian } -// tag, _, _ := matcher.Match(preferred...) +// handler(w http.ResponseWriter, r *http.Request) { +// lang, _ := r.Cookie("lang") +// accept := r.Header.Get("Accept-Language") +// tag, _ := language.MatchStrings(matcher, lang.String(), accept) // -// In this case, the best match is Danish, as Danish is sufficiently a match to -// Norwegian to not have to fall back to the default. -// See ParseAcceptLanguage on how to handle the Accept-Language HTTP header. +// // tag should now be used for the initialization of any +// // locale-specific service. +// } // -// Selecting language-specific services +// The Matcher's Match method can be used to match Tags directly. // -// One should always use the Tag returned by the Matcher to create an instance -// of any of the language-specific services provided by the text repository. -// This prevents the mixing of languages, such as having a different language for -// messages and display names, as well as improper casing or sorting order for -// the selected language. -// Using the returned Tag also allows user-defined settings, such as collation -// order or numbering system to be transparently passed as options. +// Matchers are aware of the intricacies of equivalence between languages, such +// as deprecated subtags, legacy tags, macro languages, mutual +// intelligibility between scripts and languages, and transparently passing +// BCP 47 user configuration. +// For instance, it will know that a reader of Bokmål Danish can read Norwegian +// and will know that Cantonese ("yue") is a good match for "zh-HK". // -// If you have language-specific data in your application, however, it will in -// most cases suffice to use the index returned by the matcher to identify -// the user language. -// The following loop provides an alternative in case this is not sufficient: // -// supported := map[language.Tag]data{ -// language.English: enData, -// language.MustParse("en-AU"): enAUData, -// language.Danish: daData, -// language.Chinese: zhData, -// } -// tag, _, _ := matcher.Match(preferred...) -// for ; tag != language.Und; tag = tag.Parent() { -// if v, ok := supported[tag]; ok { -// return v -// } -// } -// return enData // should not reach here +// Using match results // -// Repeatedly taking the Parent of the tag returned by Match will eventually -// match one of the tags used to initialize the Matcher. +// To guarantee a consistent user experience to the user it is important to +// use the same language tag for the selection of any locale-specific services. +// For example, it is utterly confusing to substitute spelled-out numbers +// or dates in one language in text of another language. +// More subtly confusing is using the wrong sorting order or casing +// algorithm for a certain language. +// +// All the packages in x/text that provide locale-specific services +// (e.g. collate, cases) should be initialized with the tag that was +// obtained at the start of an interaction with the user. +// +// Note that Tag that is returned by Match and MatchString may differ from any +// of the supported languages, as it may contain carried over settings from +// the user tags. +// This may be inconvenient when your application has some additional +// locale-specific data for your supported languages. +// Match and MatchString both return the index of the matched supported tag +// to simplify associating such data with the matched tag. +// // // Canonicalization // +// If one uses the Matcher to compare languages one does not need to +// worry about canonicalization. +// +// The meaning of a Tag varies per application. The language package +// therefore delays canonicalization and preserves information as much +// as possible. The Matcher, however, will always take into account that +// two different tags may represent the same language. +// // By default, only legacy and deprecated tags are converted into their // canonical equivalent. All other information is preserved. This approach makes // the confidence scores more accurate and allows matchers to distinguish @@ -89,12 +88,15 @@ // // As a consequence, two tags that should be treated as identical according to // BCP 47 or CLDR, like "en-Latn" and "en", will be represented differently. The -// Matchers will handle such distinctions, though, and are aware of the +// Matcher handles such distinctions, though, and is aware of the // equivalence relations. The CanonType type can be used to alter the // canonicalization form. // // References // -// BCP 47 - Tags for Identifying Languages -// http://tools.ietf.org/html/bcp47 +// BCP 47 - Tags for Identifying Languages http://tools.ietf.org/html/bcp47 +// package language // import "golang.org/x/text/language" + +// TODO: explanation on how to match languages for your own locale-specific +// service.