Skip to content

Commit

Permalink
Leave out MessageFormat.parseResource() from this proposal (tc39#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
eemeli authored Dec 1, 2022
1 parent 5330080 commit 785b4fe
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 44 deletions.
72 changes: 29 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ Furthermore, localization often relies on parsing these custom formats
during the runtime or rendering of an application.

To help with this, we introduce
`Intl.MessageFormat` as a native parser and formatter for [MessageFormat 2.0] (aka "MF2") messages and resources.
`Intl.MessageFormat` as a native parser and formatter for [MessageFormat 2.0] (aka "MF2") messages.
MF2 is a specification currently being developed under the Unicode Consortium, with wide industry support.
This will allow for using MF2 messages and resources to localize web sites,
This will allow for using MF2 messages to localize web sites,
enabling the localization of the web using industry standard tooling and processes.

In addition to a syntax that is designed to be accessible by both developers and translators,
Expand All @@ -31,29 +31,29 @@ providing a shared message formatting runtime for all users.
## Use cases

The primary use case is the retrieval and resolution of localized text (i.e. a "message")
given a message resource, the locale and other options, a message identifier,
given a message source text, the locale and other options, a message identifier,
and optionally a set of runtime values.

Put together, this allows for any message ranging from the simplest to the most complex
to be defined by a developer, translated to any number of locales, and displayed to a user.

For instance, consider a relatively simple message such as

> You have 3 new notifications
In practice, this would need to account for any number of notifications,
and the plural rules of the current locale.
In a message resource, this could be defined using syntax such as:
Using [MF2 syntax], this could be defined as:

[mf2 syntax]: https://github.com/unicode-org/message-format-wg/blob/develop/spec/syntax.md

```ini
# Note! MF2 syntax is still under development; this may still change

greeting = {Hello!}

new_notifications =
match {$count}
when 0 {You have no new notifications}
when one {You have one new notification}
when * {You have {$count} new notifications}
match {$count}
when 0 {You have no new notifications}
when one {You have one new notification}
when * {You have {$count} new notifications}
```

Some parts of the full message are explicitly repeated for each case,
Expand All @@ -62,16 +62,25 @@ as this makes it significantly easier for translators to work with the message.
In code, with the API proposed below, this would be used like this:

```js
// A single message
const mf = new Intl.MessageFormat('{Hello!}', ['en']);
const source = ... // string source of the message as above
const mf = new Intl.MessageFormat(source, ['en']);
const notifications = mf.resolveMessage({ count: 1 });
notifications.toString(); // 'You have one new notification'
```

As a majority of messages do not require multiple variants,
those are of course also supported by the proposed API:

```js
// A plain message
const mf1 = new Intl.MessageFormat('{Hello!}', ['en']);
const greet = mf.resolveMessage();
greet.toString(); // 'Hello!'

// A full message resource
const source = ... // string source of resource as above
const res = Intl.MessageFormat.parseResource(source, ['en']);
const notifications = res.get('new_notifications').resolveMessage({ count: 1 });
notifications.toString(); // 'You have one new notification'
// A parametric message
const mf2 = new Intl.MessageFormat('{Hello {$place}!}', ['en']);
const greet = mf.resolveMessage({ place: 'world' });
greet.toString(); // 'Hello world!'
```

More complex use cases and usage patterns are described within the API description.
Expand All @@ -82,7 +91,7 @@ The MF2 specification is still being developed by the working group.
The API below is based upon one proposal under consideration,
but should not be considered representative of a consensus among the working group.
In particular, the API shapes of
`MessageFormatOptions`, `MessageData`, `MessageResource`, and `ResolvedMessageFormatOptions`
`MessageFormatOptions`, `MessageData`, and `ResolvedMessageFormatOptions`
will depend upon the data model chosen by the working group.

This proposal introduces one new primordial to ECMAScript, `Intl.MessageFormat`.
Expand All @@ -98,38 +107,15 @@ It contains a parsed representation of a single message for a particular locale.
interface MessageData {}
```

### MessageResource

A `MessageResource` is a plain Object representing a collection of related messages for a single locale.
Messages can be organized in a flat structure, or in hierarchy, using paths.
Conceptually, it is similar to a file containing a set of messages,
but there are no constrains implied on the underlying implementation.

```ts
type MessageResource = Map<string, MessageFormat | MessageResource>
```
### MessageFormat

The `Intl.MessageFormat` constructor creates `MessageFormat` instances for a given locale,
`MessageFormatOptions` and a `MessageData` structure.
If a string is used as the `source` argument,
it will be parsed as a MF2 syntax representation of a message.

The static method `Intl.MessageFormat.parseResource()` parses a string representation of an MF2 resource,
constructing a Map with a corresponding structure of `MessageFormat` instances for each of the resource's messages.
Its `locales` and `options` arguments are used to construct each such instance.
The remaining operations are defined on `MessageFormat` instances.
```ts
interface MessageFormat {
static parseResource(
resource: string,
locales?: string | string[],
options?: MessageFormatOptions
): MessageResource;

new (
source: MessageData | string,
locales?: string | string[],
Expand Down Expand Up @@ -176,7 +162,7 @@ interface MessageFormatOptions {
interface ResolvedMessageFormatOptions {
locales: string[],
localeMatcher: 'best fit' | 'lookup';
resource: MessageResource;
message: MessageData;
...
}

Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2290,7 +2290,7 @@
.clause-attributes-tag a {
color: #884400;
}
</style></head><body><div id="menu-toggle">☰</div><div id="menu-spacer"></div><div id="menu"><div id="menu-search"><input type="text" id="menu-search-box" placeholder="Search..."><div id="menu-search-results" class="inactive"></div></div><div id="menu-pins"><div class="menu-pane-header">Pins</div><ul id="menu-pins-list"></ul></div><div class="menu-pane-header">Table of Contents</div><div id="menu-toc"><ol class="toc"><li><span class="item-toggle-none"></span><a href="#sec-demo-clause" title="This is an emu-clause"><span class="secnum">1</span> This is an emu-clause</a></li><li><span class="item-toggle-none"></span><a href="#sec-copyright-and-software-license" title="Copyright &amp; Software License"><span class="secnum">A</span> Copyright &amp; Software License</a></li></ol></div></div><div id="spec-container"><h1 class="version">Stage -1 Draft / July 13, 2022</h1><h1 class="title">Proposal Title Goes Here</h1>
</style></head><body><div id="menu-toggle">☰</div><div id="menu-spacer"></div><div id="menu"><div id="menu-search"><input type="text" id="menu-search-box" placeholder="Search..."><div id="menu-search-results" class="inactive"></div></div><div id="menu-pins"><div class="menu-pane-header">Pins</div><ul id="menu-pins-list"></ul></div><div class="menu-pane-header">Table of Contents</div><div id="menu-toc"><ol class="toc"><li><span class="item-toggle-none"></span><a href="#sec-demo-clause" title="This is an emu-clause"><span class="secnum">1</span> This is an emu-clause</a></li><li><span class="item-toggle-none"></span><a href="#sec-copyright-and-software-license" title="Copyright &amp; Software License"><span class="secnum">A</span> Copyright &amp; Software License</a></li></ol></div></div><div id="spec-container"><h1 class="version">Stage -1 Draft / September 11, 2022</h1><h1 class="title">Proposal Title Goes Here</h1>

<emu-clause id="sec-demo-clause">
<h1><span class="secnum">1</span> This is an emu-clause</h1>
Expand Down

0 comments on commit 785b4fe

Please sign in to comment.