htmlindex.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2015 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. //go:generate go run gen.go
  5. // Package htmlindex maps character set encoding names to Encodings as
  6. // recommended by the W3C for use in HTML 5. See http://www.w3.org/TR/encoding.
  7. package htmlindex
  8. // TODO: perhaps have a "bare" version of the index (used by this package) that
  9. // is not pre-loaded with all encodings. Global variables in encodings prevent
  10. // the linker from being able to purge unneeded tables. This means that
  11. // referencing all encodings, as this package does for the default index, links
  12. // in all encodings unconditionally.
  13. //
  14. // This issue can be solved by either solving the linking issue (see
  15. // https://github.com/golang/go/issues/6330) or refactoring the encoding tables
  16. // (e.g. moving the tables to internal packages that do not use global
  17. // variables).
  18. // TODO: allow canonicalizing names
  19. import (
  20. "errors"
  21. "strings"
  22. "sync"
  23. "golang.org/x/text/encoding"
  24. "golang.org/x/text/encoding/internal/identifier"
  25. "golang.org/x/text/language"
  26. )
  27. var (
  28. errInvalidName = errors.New("htmlindex: invalid encoding name")
  29. errUnknown = errors.New("htmlindex: unknown Encoding")
  30. errUnsupported = errors.New("htmlindex: this encoding is not supported")
  31. )
  32. var (
  33. matcherOnce sync.Once
  34. matcher language.Matcher
  35. )
  36. // LanguageDefault returns the canonical name of the default encoding for a
  37. // given language.
  38. func LanguageDefault(tag language.Tag) string {
  39. matcherOnce.Do(func() {
  40. tags := []language.Tag{}
  41. for _, t := range strings.Split(locales, " ") {
  42. tags = append(tags, language.MustParse(t))
  43. }
  44. matcher = language.NewMatcher(tags, language.PreferSameScript(true))
  45. })
  46. _, i, _ := matcher.Match(tag)
  47. return canonical[localeMap[i]] // Default is Windows-1252.
  48. }
  49. // Get returns an Encoding for one of the names listed in
  50. // http://www.w3.org/TR/encoding using the Default Index. Matching is case-
  51. // insensitive.
  52. func Get(name string) (encoding.Encoding, error) {
  53. x, ok := nameMap[strings.ToLower(strings.TrimSpace(name))]
  54. if !ok {
  55. return nil, errInvalidName
  56. }
  57. return encodings[x], nil
  58. }
  59. // Name reports the canonical name of the given Encoding. It will return
  60. // an error if e is not associated with a supported encoding scheme.
  61. func Name(e encoding.Encoding) (string, error) {
  62. id, ok := e.(identifier.Interface)
  63. if !ok {
  64. return "", errUnknown
  65. }
  66. mib, _ := id.ID()
  67. if mib == 0 {
  68. return "", errUnknown
  69. }
  70. v, ok := mibMap[mib]
  71. if !ok {
  72. return "", errUnsupported
  73. }
  74. return canonical[v], nil
  75. }