Documentation

Overview

Package catmsg contains support types for package x/text/message/catalog.

This package contains the low-level implementations of Message used by the catalog package and provides primitives for other packages to implement their own. For instance, the plural package provides functionality for selecting translation strings based on the plural category of substitution arguments.

Encoding and Decoding

Catalogs store Messages encoded as a single string. Compiling a message into a string both results in compacter representation and speeds up evaluation.

A Message must implement a Compile method to convert its arbitrary representation to a string. The Compile method takes an Encoder which facilitates serializing the message. Encoders also provide more context of the messages's creation (such as for which language the message is intended), which may not be known at the time of the creation of the message.

Each message type must also have an accompanying decoder registered to decode the message. This decoder takes a Decoder argument which provides the counterparts for the decoding.

Renderers

A Decoder must be initialized with a Renderer implementation. These implementations must be provided by packages that use Catalogs, typically formatting packages such as x/text/message. A typical user will not need to worry about this type; it is only relevant to packages that do string formatting and want to use the catalog package to handle localized strings.

A package that uses catalogs for selecting strings receives selection results as sequence of substrings passed to the Renderer. The following snippet shows how to express the above example using the message package.

message.Set(language.English, "You are %d minute(s) late.",
    catalog.Var("minutes", plural.Select(1, "one", "minute")),
    catalog.String("You are %[1]d ${minutes} late."))

p := message.NewPrinter(language.English)
p.Printf("You are %d minute(s) late.", 5) // always 5 minutes late.

To evaluate the Printf, package message wraps the arguments in a Renderer that is passed to the catalog for message decoding. The call sequence that results from evaluating the above message, assuming the person is rather tardy, is:

Render("You are %[1]d ")
Arg(1)
Render("minutes")
Render(" late.")

The calls to Arg is caused by the plural.Select execution, which evaluates the argument to determine whether the singular or plural message form should be selected. The calls to Render reports the partial results to the message package for further evaluation.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrIncomplete indicates a compiled message does not define translations
	// for all possible argument values. If this message is returned, evaluating
	// a message may result in the ErrNoMatch error.
	ErrIncomplete = errors.New("catmsg: incomplete message; may not give result for all inputs")

	// ErrNoMatch indicates no translation message matched the given input
	// parameters when evaluating a message.
	ErrNoMatch = errors.New("catmsg: no translation for inputs")
)

Functions

func Compile

func Compile(tag language.Tag, macros Dictionary, m Message) (data string, err error)

    Compile converts a Message to a data string that can be stored in a Catalog. The resulting string can subsequently be decoded by passing to the Execute method of a Decoder.

    Types

    type Affix

    type Affix struct {
    	Message Message
    	Prefix  string
    	Suffix  string
    }

      Affix is a message that adds a prefix and suffix to another message. This is mostly used add back whitespace to a translation that was stripped before sending it out.

      func (Affix) Compile

      func (a Affix) Compile(e *Encoder) (err error)

        Compile implements Message.

        type Decoder

        type Decoder struct {
        	// contains filtered or unexported fields
        }

          A Decoder deserializes and evaluates messages that are encoded by an encoder.

          func NewDecoder

          func NewDecoder(tag language.Tag, r Renderer, macros Dictionary) *Decoder

            NewDecoder returns a new Decoder.

            Decoders are designed to be reused for multiple invocations of Execute. Only one goroutine may call Execute concurrently.

            func (*Decoder) Arg

            func (d *Decoder) Arg(i int) interface{}

              Arg implements Renderer.

              During evaluation of macros, the argument positions may be mapped to arguments that differ from the original call.

              func (*Decoder) DecodeString

              func (d *Decoder) DecodeString() string

                DecodeString decodes a string that was encoded with EncodeString and advances the position.

                func (*Decoder) DecodeUint

                func (d *Decoder) DecodeUint() uint64

                  DecodeUint decodes a number that was encoded with EncodeUint and advances the position.

                  func (*Decoder) Done

                  func (d *Decoder) Done() bool

                    Done reports whether there are more bytes to process in this message.

                    func (*Decoder) Execute

                    func (d *Decoder) Execute(msg string) error

                      Execute decodes and evaluates msg.

                      Only one goroutine may call execute.

                      func (*Decoder) ExecuteMessage

                      func (d *Decoder) ExecuteMessage() bool

                        ExecuteMessage decodes and executes the message at the current position.

                        func (*Decoder) ExecuteSubstitution

                        func (d *Decoder) ExecuteSubstitution()

                          ExecuteSubstitution executes the message corresponding to the substitution as encoded by EncodeSubstitution.

                          func (*Decoder) Language

                          func (d *Decoder) Language() language.Tag

                            Language returns the language in which the message is being rendered.

                            The destination language may be a child language of the language used for encoding. For instance, a decoding language of "pt-PT"" is consistent with an encoding language of "pt".

                            func (*Decoder) Render

                            func (d *Decoder) Render(s string)

                              Render implements Renderer.

                              func (*Decoder) SkipMessage

                              func (d *Decoder) SkipMessage()

                                SkipMessage skips the message at the current location and advances the position.

                                type Dictionary

                                type Dictionary interface {
                                	// Lookup returns the message for the given key. It returns false for ok if
                                	// such a message could not be found.
                                	Lookup(key string) (data string, ok bool)
                                }

                                  A Dictionary specifies a source of messages, including variables or macros.

                                  type Encoder

                                  type Encoder struct {
                                  	// contains filtered or unexported fields
                                  }

                                    An Encoder serializes a Message to a string.

                                    func (*Encoder) EncodeMessage

                                    func (e *Encoder) EncodeMessage(m Message) error

                                      EncodeMessage serializes the given message inline at the current position.

                                      func (*Encoder) EncodeMessageType

                                      func (e *Encoder) EncodeMessageType(h Handle)

                                        EncodeMessageType marks the current message to be of type h.

                                        It must be the first call of a Message's Compile method.

                                        func (*Encoder) EncodeString

                                        func (e *Encoder) EncodeString(s string)

                                          EncodeString encodes s.

                                          func (*Encoder) EncodeSubstitution

                                          func (e *Encoder) EncodeSubstitution(name string, arguments ...int)

                                            EncodeSubstitution inserts a resolved reference to a variable or macro.

                                            This call must be matched with a call to ExecuteSubstitution at decoding time.

                                            func (*Encoder) EncodeUint

                                            func (e *Encoder) EncodeUint(x uint64)

                                              EncodeUint encodes x.

                                              func (*Encoder) Language

                                              func (e *Encoder) Language() language.Tag

                                                Language reports the language for which the encoded message will be stored in the Catalog.

                                                type FirstOf

                                                type FirstOf []Message

                                                  FirstOf is a message type that prints the first message in the sequence that resolves to a match for the given substitution arguments.

                                                  func (FirstOf) Compile

                                                  func (s FirstOf) Compile(e *Encoder) error

                                                    Compile implements Message.

                                                    type Handle

                                                    type Handle int

                                                      A Handle refers to a registered message type.

                                                      func Register

                                                      func Register(name string, handler Handler) Handle

                                                        Register records the existence of a message type and returns a Handle that can be used in the Encoder's EncodeMessageType method to create such messages. The prefix of the name should be the package path followed by an optional disambiguating string. Register will panic if a handle for the same name was already registered.

                                                        type Handler

                                                        type Handler func(d *Decoder) bool

                                                          A Handler decodes and evaluates data compiled by a Message and sends the result to the Decoder. The output may depend on the value of the substitution arguments, accessible by the Decoder's Arg method. The Handler returns false if there is no translation for the given substitution arguments.

                                                          type Message

                                                          type Message interface {
                                                          	// Compile encodes the format string(s) of the message as a string for later
                                                          	// evaluation.
                                                          	//
                                                          	// The first call Compile makes on the encoder must be EncodeMessageType.
                                                          	// The handle passed to this call may either be a handle returned by
                                                          	// Register to encode a single custom message, or HandleFirst followed by
                                                          	// a sequence of calls to EncodeMessage.
                                                          	//
                                                          	// Compile must return ErrIncomplete if it is possible for evaluation to
                                                          	// not match any translation for a given set of formatting parameters.
                                                          	// For example, selecting a translation based on plural form may not yield
                                                          	// a match if the form "Other" is not one of the selectors.
                                                          	//
                                                          	// Compile may return any other application-specific error. For backwards
                                                          	// compatibility with package like fmt, which often do not do sanity
                                                          	// checking of format strings ahead of time, Compile should still make an
                                                          	// effort to have some sensible fallback in case of an error.
                                                          	Compile(e *Encoder) error
                                                          }

                                                            A Message holds a collection of translations for the same phrase that may vary based on the values of substitution arguments.

                                                            type Raw

                                                            type Raw string

                                                              Raw is a message consisting of a single format string that is passed as is to the Renderer.

                                                              Note that a Renderer may still do its own variable substitution.

                                                              func (Raw) Compile

                                                              func (r Raw) Compile(e *Encoder) (err error)

                                                                Compile implements Message.

                                                                type Renderer

                                                                type Renderer interface {
                                                                	// Render renders the given string. The given string may be interpreted as a
                                                                	// format string, such as the one used by the fmt package or a template.
                                                                	Render(s string)
                                                                
                                                                	// Arg returns the i-th argument passed to format a message. This method
                                                                	// should return nil if there is no such argument. Messages need access to
                                                                	// arguments to allow selecting a message based on linguistic features of
                                                                	// those arguments.
                                                                	Arg(i int) interface{}
                                                                }

                                                                  A Renderer renders a Message.

                                                                  type String

                                                                  type String string

                                                                    String is a message consisting of a single format string which contains placeholders that may be substituted with variables.

                                                                    Variable substitutions are marked with placeholders and a variable name of the form ${name}. Any other substitutions such as Go templates or printf-style substitutions are left to be done by the Renderer.

                                                                    When evaluation a string interpolation, a Renderer will receive separate calls for each placeholder and interstitial string. For example, for the message: "%[1]v ${invites} %[2]v to ${their} party." The sequence of calls is:

                                                                    d.Render("%[1]v ")
                                                                    d.Arg(1)
                                                                    d.Render(resultOfInvites)
                                                                    d.Render(" %[2]v to ")
                                                                    d.Arg(2)
                                                                    d.Render(resultOfTheir)
                                                                    d.Render(" party.")
                                                                    

                                                                    where the messages for "invites" and "their" both use a plural.Select referring to the first argument.

                                                                    Strings may also invoke macros. Macros are essentially variables that can be reused. Macros may, for instance, be used to make selections between different conjugations of a verb. See the catalog package description for an overview of macros.

                                                                    func (String) Compile

                                                                    func (s String) Compile(e *Encoder) (err error)

                                                                      Compile implements Message. It parses the placeholder formats and returns any error.

                                                                      type Var

                                                                      type Var struct {
                                                                      	Name    string
                                                                      	Message Message
                                                                      }

                                                                        Var defines a message that can be substituted for a placeholder of the same name. If an expression does not result in a string after evaluation, Name is used as the substitution. For example:

                                                                        Var{
                                                                          Name:    "minutes",
                                                                          Message: plural.Select(1, "one", "minute"),
                                                                        }
                                                                        

                                                                        will resolve to minute for singular and minutes for plural forms.

                                                                        func (*Var) Compile

                                                                        func (v *Var) Compile(e *Encoder) error

                                                                          Compile implements Message.

                                                                          Note that this method merely registers a variable; it does not create an encoded message.