@americana/diplomat 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -24
- package/dist/example/index.js +4 -5
- package/dist/index.js +6 -763
- package/dist/index.js.map +7 -0
- package/index.d.ts +85 -0
- package/index.js +238 -146
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -2,11 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
Diplomat prepares your interactive map for an international audience. With a few lines of code, your [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js/)–powered map will speak the user’s preferred language while informing them about local languages the world over.
|
|
4
4
|
|
|
5
|
-
| Before
|
|
6
|
-
|
|
|
7
|
-
| <img src="docs/navajo-nation.png" width="400" alt="Navajo Nation;Naabeehó Bináhásdzo">
|
|
8
|
-
| <img src="docs/north-sea.png" width="400" alt="North Sea / Nordsee / Noordzee / Nordsøen / Nordsjøen / Mer du Nord">
|
|
9
|
-
| <img src="docs/section-ross.png" width="400" alt="Ross Avenue;
|
|
5
|
+
| Before | After |
|
|
6
|
+
| ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| <img src="docs/navajo-nation.png" width="400" alt="Navajo Nation;Naabeehó Bináhásdzo"> | [<img src="docs/navajo-nation-es.png" width="400" alt="Nación Navajo (Navajo Nation • Naabeehó Bináhásdzo)">](https://americanamap.org/#map=9/36.2134/-109.2837&language=es) |
|
|
8
|
+
| <img src="docs/north-sea.png" width="400" alt="North Sea / Nordsee / Noordzee / Nordsøen / Nordsjøen / Mer du Nord"> | [<img src="docs/north-sea-la.png" width="400" alt="Mare Germanicum">](https://americanamap.org/#map=4/56/3&language=la) |
|
|
9
|
+
| <img src="docs/section-ross.png" width="400" alt="Ross Avenue;Tennessee Avenue at Rhode Island Avenue;Section Avenue"> | [<img src="docs/section-ross-en.png" width="400" alt="Ross Avenue • Tennessee Avenue at Rhode Island Avenue • Section Avenue">](https://americanamap.org/#map=17/39.168568/-84.460075) |
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
Diplomat gives all parties a win-win:
|
|
14
|
+
|
|
15
|
+
- Tailors labels to the user’s preferred language.
|
|
16
|
+
- Respects multilingualism with optional dual language labels: both the user’s preferred language and the local native language.
|
|
17
|
+
- Recognizes any language, dialect, or script out of the box with sophisticated language code matching.
|
|
18
|
+
|
|
19
|
+
Diplomat lets your designer save face:
|
|
20
|
+
|
|
21
|
+
- Uses space efficiently with both multiline and inline label layouts.
|
|
22
|
+
- Deduplicates names within a label to avoid clutter.
|
|
23
|
+
- Preserves diacritics in English exonyms where appropriate.
|
|
24
|
+
- Respects right-to-left and vertical text layouts.
|
|
25
|
+
|
|
26
|
+
Diplomat works quietly behind the scenes:
|
|
27
|
+
|
|
28
|
+
- Changes the style on the fly at runtime – no need to publish a new style or tileset for every language.
|
|
29
|
+
- You choose which style layers to localize, or localize them all automatically.
|
|
30
|
+
- Supports multiple popular vector tile schemas without hacky workarounds, plus custom vector tilesets and GeoJSON sources.
|
|
31
|
+
|
|
32
|
+
All localization is subject to the availability of localized names in the map data source. See [the caveats](#caveats) for more details.
|
|
10
33
|
|
|
11
34
|
## Requirements
|
|
12
35
|
|
|
@@ -21,7 +44,7 @@ With additional configuration, Diplomat supports even more vector tilesets, incl
|
|
|
21
44
|
|
|
22
45
|
- [Mapbox Streets](https://docs.mapbox.com/data/tilesets/reference/mapbox-streets-v8/#names)
|
|
23
46
|
- [OpenHistoricalMap](https://wiki.openstreetmap.org/wiki/OpenHistoricalMap/Reuse#Vector_tiles)
|
|
24
|
-
- [Shortbread](https://shortbread-tiles.org/schema/)
|
|
47
|
+
- [Shortbread](https://shortbread-tiles.org/schema/) implementations, e.g., [OpenStreetMap.org](https://vector.openstreetmap.org/), [VersaTiles](https://github.com/versatiles-org/versatiles-generator/)
|
|
25
48
|
|
|
26
49
|
## Installation
|
|
27
50
|
|
|
@@ -35,11 +58,17 @@ Alternatively, you can include the plugin as a standalone script from a CDN such
|
|
|
35
58
|
|
|
36
59
|
## Usage
|
|
37
60
|
|
|
61
|
+
Import Diplomat as a module:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import * as Diplomat from "@americana/diplomat";
|
|
65
|
+
```
|
|
66
|
+
|
|
38
67
|
After creating an instance of `maplibregl.Map`, register an event listener for the `styledata` event that localizes the map:
|
|
39
68
|
|
|
40
69
|
```js
|
|
41
70
|
map.once("styledata", (event) => {
|
|
42
|
-
|
|
71
|
+
Diplomat.localizeStyle(map);
|
|
43
72
|
});
|
|
44
73
|
```
|
|
45
74
|
|
|
@@ -47,8 +76,8 @@ If your stylesheet uses a tileset that formats the name keys differently, such a
|
|
|
47
76
|
|
|
48
77
|
```js
|
|
49
78
|
map.once("styledata", (event) => {
|
|
50
|
-
let locales =
|
|
51
|
-
|
|
79
|
+
let locales = Diplomat.getLocales();
|
|
80
|
+
Diplomat.localizeStyle(map, locales, {
|
|
52
81
|
localizedNamePropertyFormat: "name_$1",
|
|
53
82
|
});
|
|
54
83
|
});
|
|
@@ -58,15 +87,11 @@ If you set the `hash` option to a string when creating the `Map`, you can have t
|
|
|
58
87
|
|
|
59
88
|
```js
|
|
60
89
|
addEventListener("hashchange", (event) => {
|
|
61
|
-
let oldLanguage =
|
|
62
|
-
|
|
63
|
-
);
|
|
64
|
-
let newLanguage = maplibregl.Diplomat.getLanguageFromURL(
|
|
65
|
-
new URL(event.newURL),
|
|
66
|
-
);
|
|
90
|
+
let oldLanguage = Diplomat.getLanguageFromURL(new URL(event.oldURL));
|
|
91
|
+
let newLanguage = Diplomat.getLanguageFromURL(new URL(event.newURL));
|
|
67
92
|
|
|
68
93
|
if (oldLanguage !== newLanguage) {
|
|
69
|
-
|
|
94
|
+
Diplomat.localizeStyle(map);
|
|
70
95
|
}
|
|
71
96
|
});
|
|
72
97
|
```
|
|
@@ -75,7 +100,7 @@ Similarly, you can immediately respond to any change the user makes to their bro
|
|
|
75
100
|
|
|
76
101
|
```js
|
|
77
102
|
addEventListener("languagechange", (event) => {
|
|
78
|
-
|
|
103
|
+
Diplomat.localizeStyle(map);
|
|
79
104
|
});
|
|
80
105
|
```
|
|
81
106
|
|
|
@@ -95,7 +120,7 @@ Each of the supported properties may be set to a list of values separated by [se
|
|
|
95
120
|
|
|
96
121
|
## API
|
|
97
122
|
|
|
98
|
-
This plugin adds several
|
|
123
|
+
This plugin adds several symbols to a `maplibregl.Diplomat` namespace and adds a single method to each instance of `maplibregl.Map`. The following documentation uses the notation `maplibregl.Diplomat.*` in case you include Diplomat as a script. However, if you import Diplomat as a module, these symbols are directly imported into your code, without any namespacing.
|
|
99
124
|
|
|
100
125
|
### `maplibregl.Diplomat.localizedName`
|
|
101
126
|
|
|
@@ -213,20 +238,53 @@ Example:
|
|
|
213
238
|
maplibregl.Diplomat.getLocales().includes("en");
|
|
214
239
|
```
|
|
215
240
|
|
|
216
|
-
### `maplibregl.
|
|
241
|
+
### `maplibregl.Diplomat.getRelatedLanguageTags()`
|
|
242
|
+
|
|
243
|
+
Returns an array of the language tags related to the given language tag, sorted from most specific to least specific.
|
|
244
|
+
|
|
245
|
+
Parameters:
|
|
246
|
+
|
|
247
|
+
- **`tag`** (`string`): The language tag that the returned language tags are related to.
|
|
248
|
+
|
|
249
|
+
Returns a sorted array of related language tags, or an empty array if `tag` is malformed.
|
|
250
|
+
|
|
251
|
+
Example:
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
maplibregl.Diplomat.getRelatedLanguageTags("sr-RS").includes("sr-Cyrl");
|
|
255
|
+
maplibregl.Diplomat.getRelatedLanguageTags("zh").includes("zh-Hans-CN");
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### `maplibregl.Diplomat.localizeStyle()`
|
|
217
259
|
|
|
218
260
|
Updates each style layer's `text-field` value to match the given locales, upgrading any unlocalizable layer along the way.
|
|
219
261
|
|
|
220
|
-
|
|
262
|
+
If neither `options.layers` nor `options.sourceLayers` is specified in `options`, this function makes localizable any style layer that gets the feature property specified in `options.unlocalizedNameProperty`, or `name` by default.
|
|
221
263
|
|
|
222
264
|
Parameters:
|
|
223
265
|
|
|
224
|
-
- **`
|
|
266
|
+
- **`map`** (`maplibregl.Map`): The map to localize.
|
|
225
267
|
- **`locales`** (`[string]`): The locales to insert into each layer, as a comma-separated list of [IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag). Uses the `language` URL hash parameter or browser preferences by default.
|
|
226
268
|
- **`options`** (`object`):
|
|
269
|
+
- **`layers`** (`[string]`): The style layers with these IDs will be made localizable.
|
|
270
|
+
- **`sourceLayers`** (`[string]`): The style layers that use these source layers will be made localizable. These are source layer IDs, not style layer IDs.
|
|
227
271
|
- **`unlocalizedNameProperty`** (`string`): The name of the property holding the unlocalized name. `name` by default.
|
|
228
|
-
- **`localizedNamePropertyFormat`** (`string`):
|
|
229
|
-
- **`
|
|
272
|
+
- **`localizedNamePropertyFormat`** (`string`): The format of properties holding localized names, where `$1` is replaced by an IETF language tag. `name:$1` by default.
|
|
273
|
+
- **`glossLocalNames`** (`boolean`): Whether to format each label as a dual language label including a local name gloss.
|
|
274
|
+
- **`uppercaseCountryNames`** (`boolean`): Whether to write country names in all uppercase, respecting the locale’s case conventions.
|
|
275
|
+
|
|
276
|
+
Example:
|
|
277
|
+
|
|
278
|
+
```js
|
|
279
|
+
maplibregl.Diplomat.localizeStyle(map, ["eo"], {
|
|
280
|
+
sourceLayers: ["place"],
|
|
281
|
+
glossLocalNames: true,
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### `maplibregl.Map.prototype.localizeStyle()`
|
|
286
|
+
|
|
287
|
+
A wrapper for [`maplibregl.Diplomat.localizeStyle()`](#maplibregldiplomatlocalizestyle) that does not require passing in a `maplibregl.Map`. Only available when including Diplomat as a script.
|
|
230
288
|
|
|
231
289
|
Example:
|
|
232
290
|
|
|
@@ -242,7 +300,7 @@ Diplomat only switches between languages that are present in the stylesheet’s
|
|
|
242
300
|
|
|
243
301
|
By default, MapLibre GL JS does not support bidirectional text. Arabic, Hebrew, and other right-to-left languages will be unreadable unless you [install the mapbox-gl-rtl-text plugin](https://maplibre.org/maplibre-gl-js/docs/examples/add-support-for-right-to-left-scripts/).
|
|
244
302
|
|
|
245
|
-
Diplomat
|
|
303
|
+
Diplomat performs basic language fallbacks according to the [ICU locale fallback algorithm](https://unicode-org.github.io/icu/userguide/locale/#fallback). Additionally, it implements the [Likely Subtags](https://www.unicode.org/reports/tr35/#Likely_Subtags) algorithm of Unicode Technical Standard #35, so for example requesting either `zh` or `cmn` returns a name tagged as `zh-Hans-CN`, among other variations. However, in general, it does not fall back to a related but distinct language code, such as from `sr-Cyrl` to `ru` or from `nb` to `no`. Instead, the user can [set their preferred languages](https://www.w3.org/International/questions/qa-lang-priorities) in their browser or operating system settings.
|
|
246
304
|
|
|
247
305
|
For historical reasons, [OpenStreetMap’s coverage in many reasons](https://wiki.openstreetmap.org/wiki/Multilingual_names) encodes multiple local names separated by human-readable punctuation. Diplomat makes no attempt to guess which punctuation is part of a name and which punctuation delimits two names.
|
|
248
306
|
|
package/dist/example/index.js
CHANGED
|
@@ -83,11 +83,10 @@ addEventListener("load", () => {
|
|
|
83
83
|
);
|
|
84
84
|
|
|
85
85
|
map.once("styledata", (event) => {
|
|
86
|
-
map.
|
|
87
|
-
"place
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
);
|
|
86
|
+
map.localizeStyle(maplibregl.Diplomat.getLocales(), {
|
|
87
|
+
sourceLayers: ["place"],
|
|
88
|
+
glossLocalNames: true,
|
|
89
|
+
});
|
|
91
90
|
map.localizeStyle(maplibregl.Diplomat.getLocales(), {
|
|
92
91
|
uppercaseCountryNames: true,
|
|
93
92
|
});
|