@markuplint/i18n 3.0.0-dev.177 → 3.0.0-dev.290
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/$schema.json +1 -0
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.js +5 -0
- package/lib/cjs/translator.d.ts +6 -0
- package/lib/cjs/translator.js +107 -0
- package/lib/cjs/types.d.ts +16 -0
- package/lib/cjs/types.js +2 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -5
- package/lib/translator.d.ts +2 -4
- package/lib/translator.js +8 -16
- package/lib/types.d.ts +8 -8
- package/lib/types.js +1 -2
- package/locales/ja.json +1 -0
- package/package.json +20 -6
- package/test/index.spec.js +0 -273
package/$schema.json
CHANGED
|
@@ -268,6 +268,7 @@
|
|
|
268
268
|
"the list of {0}": { "type": "string" },
|
|
269
269
|
"the max number of elements required is {0}": { "type": "string" },
|
|
270
270
|
"the same {0} as {1}": { "type": "string" },
|
|
271
|
+
"the user agent will automatically use \"{0}\" instead": { "type": "string" },
|
|
271
272
|
"there is more content than it needs": { "type": "string" },
|
|
272
273
|
"unexpected {0}": { "type": "string" },
|
|
273
274
|
"unique {0}": { "type": "string" },
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.translator = void 0;
|
|
4
|
+
var translator_js_1 = require("./translator.js");
|
|
5
|
+
Object.defineProperty(exports, "translator", { enumerable: true, get: function () { return translator_js_1.translator; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LocaleSet, Primitive, Translator } from './types.js';
|
|
2
|
+
export declare function translator(localeSet?: LocaleSet): Translator;
|
|
3
|
+
/**
|
|
4
|
+
* @experimental
|
|
5
|
+
*/
|
|
6
|
+
export declare function taggedTemplateTranslator(localeSet?: LocaleSet): (strings: Readonly<TemplateStringsArray>, ...keys: readonly Primitive[]) => string;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.taggedTemplateTranslator = exports.translator = void 0;
|
|
4
|
+
const defaultListFormat = {
|
|
5
|
+
quoteStart: '"',
|
|
6
|
+
quoteEnd: '"',
|
|
7
|
+
separator: ', ',
|
|
8
|
+
};
|
|
9
|
+
function translator(localeSet) {
|
|
10
|
+
return (messageTmpl, ...keywords) => {
|
|
11
|
+
let message = messageTmpl;
|
|
12
|
+
if (typeof messageTmpl !== 'string') {
|
|
13
|
+
const format = localeSet?.listFormat ?? defaultListFormat;
|
|
14
|
+
return `${format.quoteStart}${messageTmpl
|
|
15
|
+
.map(keyword => translateKeyword(keyword, '', localeSet))
|
|
16
|
+
.join(`${format.quoteEnd}${format.separator}${format.quoteStart}`)}${format.quoteEnd}`;
|
|
17
|
+
}
|
|
18
|
+
const input = messageTmpl;
|
|
19
|
+
if (keywords.length === 0) {
|
|
20
|
+
return translateKeyword(messageTmpl, '', localeSet);
|
|
21
|
+
}
|
|
22
|
+
const noTranslateIndex = Array.from(messageTmpl.matchAll(/(?<=\{)[0-9]+(?=\*\})/g)).map(m => m[0]);
|
|
23
|
+
const key = removeNoTranslateMark(messageTmpl).toLowerCase();
|
|
24
|
+
const sentence = localeSet?.sentences?.[key];
|
|
25
|
+
messageTmpl = sentence ?? key;
|
|
26
|
+
messageTmpl =
|
|
27
|
+
removeNoTranslateMark(input.toLowerCase()) === messageTmpl ? removeNoTranslateMark(input) : messageTmpl;
|
|
28
|
+
message = messageTmpl.replace(/\{([0-9]+)(?::([c]))?\}/g, ($0, number, flag) => {
|
|
29
|
+
const num = parseInt(number);
|
|
30
|
+
if (isNaN(num)) {
|
|
31
|
+
return $0;
|
|
32
|
+
}
|
|
33
|
+
const keyword = keywords[num] != null ? toString(keywords[num], localeSet?.locale) : '';
|
|
34
|
+
// No translate
|
|
35
|
+
if (noTranslateIndex.includes(number)) {
|
|
36
|
+
return keyword;
|
|
37
|
+
}
|
|
38
|
+
return translateKeyword(keyword, flag, localeSet);
|
|
39
|
+
});
|
|
40
|
+
return message;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
exports.translator = translator;
|
|
44
|
+
/**
|
|
45
|
+
* @experimental
|
|
46
|
+
*/
|
|
47
|
+
function taggedTemplateTranslator(localeSet) {
|
|
48
|
+
const t = translator(localeSet);
|
|
49
|
+
return (strings, ...keys) => {
|
|
50
|
+
let i = 0;
|
|
51
|
+
const template = strings.raw
|
|
52
|
+
.map((place, index) => {
|
|
53
|
+
if (index === strings.raw.length - 1)
|
|
54
|
+
return place;
|
|
55
|
+
const value = keys[i];
|
|
56
|
+
const cFlag = /^c:/.test(typeof value === 'string' ? value : '') ? ':c' : '';
|
|
57
|
+
return `${place}{${i++}${cFlag}}`;
|
|
58
|
+
})
|
|
59
|
+
.join('');
|
|
60
|
+
return t(template, ...keys);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.taggedTemplateTranslator = taggedTemplateTranslator;
|
|
64
|
+
function translateKeyword(keyword, flag, localeSet) {
|
|
65
|
+
// No translate
|
|
66
|
+
if (/^%[^%]+%$/.test(keyword)) {
|
|
67
|
+
return keyword.replace(/^%|%$/g, '');
|
|
68
|
+
}
|
|
69
|
+
// "%" prefix and suffix escaped
|
|
70
|
+
keyword = keyword.replace(/^%%|%%$/g, '%');
|
|
71
|
+
const key = flag ? `${flag}:${keyword}` : keyword;
|
|
72
|
+
const replacedWord =
|
|
73
|
+
// finding with flag
|
|
74
|
+
localeSet?.keywords?.[key.toLowerCase()] ||
|
|
75
|
+
// finding without flag
|
|
76
|
+
localeSet?.keywords?.[keyword.toLowerCase()];
|
|
77
|
+
return replacedWord || keyword;
|
|
78
|
+
}
|
|
79
|
+
function toString(value, locale = 'en') {
|
|
80
|
+
switch (typeof value) {
|
|
81
|
+
case 'string':
|
|
82
|
+
return value;
|
|
83
|
+
case 'number':
|
|
84
|
+
return toLocaleString(value, locale);
|
|
85
|
+
case 'boolean':
|
|
86
|
+
return `${value}`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function toLocaleString(value, locale) {
|
|
90
|
+
try {
|
|
91
|
+
return value.toLocaleString(locale);
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
if (e instanceof RangeError) {
|
|
95
|
+
try {
|
|
96
|
+
return value.toLocaleString('en');
|
|
97
|
+
}
|
|
98
|
+
catch (_) {
|
|
99
|
+
// void
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return value.toString(10);
|
|
104
|
+
}
|
|
105
|
+
function removeNoTranslateMark(message) {
|
|
106
|
+
return message.replace(/(?<=\{[0-9]+)\*(?=\})/g, '');
|
|
107
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Translator = (messageTmpl: string | readonly string[], ...keywords: readonly Primitive[]) => string;
|
|
2
|
+
export type LocaleSet = {
|
|
3
|
+
readonly locale: string;
|
|
4
|
+
readonly listFormat?: ListFormat;
|
|
5
|
+
readonly keywords?: LocalesKeywords;
|
|
6
|
+
readonly sentences?: LocalesKeywords;
|
|
7
|
+
};
|
|
8
|
+
export type ListFormat = {
|
|
9
|
+
readonly quoteStart: string;
|
|
10
|
+
readonly quoteEnd: string;
|
|
11
|
+
readonly separator: string;
|
|
12
|
+
};
|
|
13
|
+
export type Primitive = string | number | boolean;
|
|
14
|
+
export type LocalesKeywords = {
|
|
15
|
+
readonly [messageId: string]: string;
|
|
16
|
+
};
|
package/lib/cjs/types.js
ADDED
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { translator } from './translator';
|
|
2
|
-
export { Translator, LocaleSet } from './types';
|
|
1
|
+
export { translator } from './translator.js';
|
|
2
|
+
export { Translator, LocaleSet } from './types.js';
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.translator = void 0;
|
|
4
|
-
var translator_1 = require("./translator");
|
|
5
|
-
Object.defineProperty(exports, "translator", { enumerable: true, get: function () { return translator_1.translator; } });
|
|
1
|
+
export { translator } from './translator.js';
|
package/lib/translator.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type { LocaleSet, Primitive, Translator } from './types';
|
|
1
|
+
import type { LocaleSet, Primitive, Translator } from './types.js';
|
|
2
2
|
export declare function translator(localeSet?: LocaleSet): Translator;
|
|
3
3
|
/**
|
|
4
4
|
* @experimental
|
|
5
5
|
*/
|
|
6
|
-
export declare function taggedTemplateTranslator(
|
|
7
|
-
localeSet?: LocaleSet,
|
|
8
|
-
): (strings: Readonly<TemplateStringsArray>, ...keys: readonly Primitive[]) => string;
|
|
6
|
+
export declare function taggedTemplateTranslator(localeSet?: LocaleSet): (strings: Readonly<TemplateStringsArray>, ...keys: readonly Primitive[]) => string;
|
package/lib/translator.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.taggedTemplateTranslator = exports.translator = void 0;
|
|
4
1
|
const defaultListFormat = {
|
|
5
2
|
quoteStart: '"',
|
|
6
3
|
quoteEnd: '"',
|
|
7
4
|
separator: ', ',
|
|
8
5
|
};
|
|
9
|
-
function translator(localeSet) {
|
|
6
|
+
export function translator(localeSet) {
|
|
10
7
|
return (messageTmpl, ...keywords) => {
|
|
11
|
-
var _a, _b;
|
|
12
8
|
let message = messageTmpl;
|
|
13
9
|
if (typeof messageTmpl !== 'string') {
|
|
14
|
-
const format =
|
|
10
|
+
const format = localeSet?.listFormat ?? defaultListFormat;
|
|
15
11
|
return `${format.quoteStart}${messageTmpl
|
|
16
12
|
.map(keyword => translateKeyword(keyword, '', localeSet))
|
|
17
13
|
.join(`${format.quoteEnd}${format.separator}${format.quoteStart}`)}${format.quoteEnd}`;
|
|
@@ -22,8 +18,8 @@ function translator(localeSet) {
|
|
|
22
18
|
}
|
|
23
19
|
const noTranslateIndex = Array.from(messageTmpl.matchAll(/(?<=\{)[0-9]+(?=\*\})/g)).map(m => m[0]);
|
|
24
20
|
const key = removeNoTranslateMark(messageTmpl).toLowerCase();
|
|
25
|
-
const sentence =
|
|
26
|
-
messageTmpl = sentence
|
|
21
|
+
const sentence = localeSet?.sentences?.[key];
|
|
22
|
+
messageTmpl = sentence ?? key;
|
|
27
23
|
messageTmpl =
|
|
28
24
|
removeNoTranslateMark(input.toLowerCase()) === messageTmpl ? removeNoTranslateMark(input) : messageTmpl;
|
|
29
25
|
message = messageTmpl.replace(/\{([0-9]+)(?::([c]))?\}/g, ($0, number, flag) => {
|
|
@@ -31,7 +27,7 @@ function translator(localeSet) {
|
|
|
31
27
|
if (isNaN(num)) {
|
|
32
28
|
return $0;
|
|
33
29
|
}
|
|
34
|
-
const keyword = keywords[num] != null ? toString(keywords[num], localeSet
|
|
30
|
+
const keyword = keywords[num] != null ? toString(keywords[num], localeSet?.locale) : '';
|
|
35
31
|
// No translate
|
|
36
32
|
if (noTranslateIndex.includes(number)) {
|
|
37
33
|
return keyword;
|
|
@@ -41,11 +37,10 @@ function translator(localeSet) {
|
|
|
41
37
|
return message;
|
|
42
38
|
};
|
|
43
39
|
}
|
|
44
|
-
exports.translator = translator;
|
|
45
40
|
/**
|
|
46
41
|
* @experimental
|
|
47
42
|
*/
|
|
48
|
-
function taggedTemplateTranslator(localeSet) {
|
|
43
|
+
export function taggedTemplateTranslator(localeSet) {
|
|
49
44
|
const t = translator(localeSet);
|
|
50
45
|
return (strings, ...keys) => {
|
|
51
46
|
let i = 0;
|
|
@@ -61,9 +56,7 @@ function taggedTemplateTranslator(localeSet) {
|
|
|
61
56
|
return t(template, ...keys);
|
|
62
57
|
};
|
|
63
58
|
}
|
|
64
|
-
exports.taggedTemplateTranslator = taggedTemplateTranslator;
|
|
65
59
|
function translateKeyword(keyword, flag, localeSet) {
|
|
66
|
-
var _a, _b;
|
|
67
60
|
// No translate
|
|
68
61
|
if (/^%[^%]+%$/.test(keyword)) {
|
|
69
62
|
return keyword.replace(/^%|%$/g, '');
|
|
@@ -73,10 +66,9 @@ function translateKeyword(keyword, flag, localeSet) {
|
|
|
73
66
|
const key = flag ? `${flag}:${keyword}` : keyword;
|
|
74
67
|
const replacedWord =
|
|
75
68
|
// finding with flag
|
|
76
|
-
|
|
77
|
-
(
|
|
69
|
+
localeSet?.keywords?.[key.toLowerCase()] ||
|
|
78
70
|
// finding without flag
|
|
79
|
-
|
|
71
|
+
localeSet?.keywords?.[keyword.toLowerCase()];
|
|
80
72
|
return replacedWord || keyword;
|
|
81
73
|
}
|
|
82
74
|
function toString(value, locale = 'en') {
|
package/lib/types.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export type Translator = (messageTmpl: string | readonly string[], ...keywords: readonly Primitive[]) => string;
|
|
2
2
|
export type LocaleSet = {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
readonly locale: string;
|
|
4
|
+
readonly listFormat?: ListFormat;
|
|
5
|
+
readonly keywords?: LocalesKeywords;
|
|
6
|
+
readonly sentences?: LocalesKeywords;
|
|
7
7
|
};
|
|
8
8
|
export type ListFormat = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
readonly quoteStart: string;
|
|
10
|
+
readonly quoteEnd: string;
|
|
11
|
+
readonly separator: string;
|
|
12
12
|
};
|
|
13
13
|
export type Primitive = string | number | boolean;
|
|
14
14
|
export type LocalesKeywords = {
|
|
15
|
-
|
|
15
|
+
readonly [messageId: string]: string;
|
|
16
16
|
};
|
package/lib/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/locales/ja.json
CHANGED
|
@@ -250,6 +250,7 @@
|
|
|
250
250
|
"the list of {0}": "{0}のリスト",
|
|
251
251
|
"the max number of elements required is {0}": "必要な要素数の最大は{0}です",
|
|
252
252
|
"the same {0} as {1}": "{1}と同等の{0}",
|
|
253
|
+
"the user agent will automatically use \"{0}\" instead": "ユーザーエージェントは自動的に「{0}」を代わりに使用します。",
|
|
253
254
|
"there is more content than it needs": "必要以上のコンテンツがあります",
|
|
254
255
|
"unexpected {0}": "期待されない{0}",
|
|
255
256
|
"unique {0}": "一意の{0}",
|
package/package.json
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/i18n",
|
|
3
|
-
"version": "3.0.0-dev.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.0-dev.290+af676442",
|
|
4
|
+
"description": "Internationalization for markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"private": false,
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./lib/index.js",
|
|
13
|
+
"require": "./lib/cjs/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./locales/en.json": {
|
|
16
|
+
"import": "./locales/en.json",
|
|
17
|
+
"require": "./locales/en.json"
|
|
18
|
+
},
|
|
19
|
+
"./locales/ja.json": {
|
|
20
|
+
"import": "./locales/ja.json",
|
|
21
|
+
"require": "./locales/ja.json"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"types": "./lib/index.d.ts",
|
|
11
25
|
"publishConfig": {
|
|
12
26
|
"access": "public"
|
|
13
27
|
},
|
|
@@ -15,8 +29,8 @@
|
|
|
15
29
|
"entryPoint": "./src/index.ts"
|
|
16
30
|
},
|
|
17
31
|
"scripts": {
|
|
18
|
-
"build": "tsc",
|
|
32
|
+
"build": "tsc; tsc --module commonjs --outDir lib/cjs",
|
|
19
33
|
"clean": "tsc --build --clean"
|
|
20
34
|
},
|
|
21
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "af6764422feecb56d1d84659028f53daf685bb78"
|
|
22
36
|
}
|
package/test/index.spec.js
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
const { taggedTemplateTranslator, translator } = require('../lib/translator');
|
|
2
|
-
|
|
3
|
-
const ja = {
|
|
4
|
-
locale: 'ja',
|
|
5
|
-
...require('../locales/ja.json'),
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
test('Listup', () => {
|
|
9
|
-
const t1 = translator();
|
|
10
|
-
expect(t1(['1', '2', '3'])).toBe('"1", "2", "3"');
|
|
11
|
-
const t2 = translator(ja);
|
|
12
|
-
expect(t2(['1', '2', '3'])).toBe('「1」「2」「3」');
|
|
13
|
-
expect(t2(['element', 'attribute', 'value'])).toBe('「要素」「属性」「値」');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test('One keyword', () => {
|
|
17
|
-
const t = translator(ja);
|
|
18
|
-
|
|
19
|
-
expect(t('element')).toBe('要素');
|
|
20
|
-
expect(t('attribute')).toBe('属性');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('No translate (EN is not affect)', () => {
|
|
24
|
-
const t = translator();
|
|
25
|
-
|
|
26
|
-
expect(t('the "{0}" {1}', 'autocomplete', 'attribute')).toBe('the "autocomplete" attribute');
|
|
27
|
-
expect(t('the "{0*}" {1}', 'autocomplete', 'attribute')).toBe('the "autocomplete" attribute');
|
|
28
|
-
expect(t('the "{0*}" {1*}', 'autocomplete', 'attribute')).toBe('the "autocomplete" attribute');
|
|
29
|
-
expect(t('the "{0}" {1*}', 'autocomplete', 'attribute')).toBe('the "autocomplete" attribute');
|
|
30
|
-
// It is an illegal syntax
|
|
31
|
-
expect(t('the "{0**}" {1**}', 'autocomplete', 'attribute')).toBe('the "{0**}" {1**}');
|
|
32
|
-
|
|
33
|
-
expect(t('element')).toBe('element');
|
|
34
|
-
expect(t('%element%')).toBe('element');
|
|
35
|
-
expect(t('%element%%')).toBe('%element%');
|
|
36
|
-
expect(t('%%element%')).toBe('%element%');
|
|
37
|
-
expect(t('%%element%%')).toBe('%element%');
|
|
38
|
-
expect(t('element%%')).toBe('element%');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('Complementize', () => {
|
|
42
|
-
const t = translator(ja);
|
|
43
|
-
|
|
44
|
-
expect(t('{0} is {1}', 'attribute', 'deprecated')).toBe('属性は非推奨です');
|
|
45
|
-
expect(t('{0} is {1:c}', 'attribute', 'deprecated')).toBe('属性は非推奨です');
|
|
46
|
-
expect(t('{0} is {1}', 'attribute', 'obsolete')).toBe('属性は廃止ずみです');
|
|
47
|
-
expect(t('{0} is {1:c}', 'attribute', 'obsolete')).toBe('属性は廃止されています');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('Complementize (EN is not affect)', () => {
|
|
51
|
-
const t = translator();
|
|
52
|
-
|
|
53
|
-
expect(t('{0} is {1}', 'attribute', 'deprecated')).toBe('attribute is deprecated');
|
|
54
|
-
expect(t('{0} is {1:c}', 'attribute', 'deprecated')).toBe('attribute is deprecated');
|
|
55
|
-
expect(t('{0} is {1}', 'attribute', 'obsolete')).toBe('attribute is obsolete');
|
|
56
|
-
expect(t('{0} is {1:c}', 'attribute', 'obsolete')).toBe('attribute is obsolete');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test('Nesting', () => {
|
|
60
|
-
const t = translator();
|
|
61
|
-
expect(t('{0} must be {1}', t('{0} of {1}', 'attribute names', 'HTML elements'), 'lowercase')).toBe(
|
|
62
|
-
'attribute names of HTML elements must be lowercase',
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const t2 = translator(ja);
|
|
66
|
-
expect(t2('{0} must be {1}', t2('{0} of {1}', 'attribute names', 'HTML elements'), 'lowercase')).toBe(
|
|
67
|
-
'HTML要素の属性名は小文字にするべきです',
|
|
68
|
-
);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('Upper/Lowser Case', () => {
|
|
72
|
-
const t = translator();
|
|
73
|
-
expect(t("It doesn't need {0}", t('the {0}', 'attribute'))).toBe("It doesn't need the attribute");
|
|
74
|
-
expect(t('"{0*}" ID', 'foo')).toBe('"foo" ID');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test('Tagged template version (@experimental)', () => {
|
|
78
|
-
const _ = taggedTemplateTranslator(ja);
|
|
79
|
-
expect(
|
|
80
|
-
_`${
|
|
81
|
-
//
|
|
82
|
-
_`${
|
|
83
|
-
//
|
|
84
|
-
_`the ${'value'}`
|
|
85
|
-
} of ${
|
|
86
|
-
//
|
|
87
|
-
_`the "${'id'}" ${'attribute'}`
|
|
88
|
-
}`
|
|
89
|
-
} is ${
|
|
90
|
-
//
|
|
91
|
-
'c:duplicated'
|
|
92
|
-
}`,
|
|
93
|
-
).toBe('属性「id」の値が重複しています');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test('ja', () => {
|
|
97
|
-
const t = translator(ja);
|
|
98
|
-
|
|
99
|
-
expect(
|
|
100
|
-
t('{0} is unmatched with the below patterns: {1}', t('the "{0}" {1}', 'foo', 'class name'), '"bar", "boo"'),
|
|
101
|
-
).toBe('クラス名「foo」は次のパターンにマッチしませんでした "bar", "boo"');
|
|
102
|
-
expect(t('{0} is {1:c}', t('the "{0}" {1}', 'color', 'attribute'), 'obsolete')).toBe(
|
|
103
|
-
'属性「color」は廃止されています',
|
|
104
|
-
);
|
|
105
|
-
expect(t('{0} is {1:c}', t('the "{0}" {1}', 'foo', 'element'), 'non-standard')).toBe('要素「foo」は非標準です');
|
|
106
|
-
expect(t('Require {0}', 'doctype')).toBe('文書型が必要です');
|
|
107
|
-
expect(t('Never {0} {1}', 'declare', 'obsolete doctype')).toBe('廃止された文書型を宣言しないでください');
|
|
108
|
-
expect(
|
|
109
|
-
t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'value'), t('the "{0}" {1}', 'id', 'attribute')), 'duplicated'),
|
|
110
|
-
).toBe('属性「id」の値が重複しています');
|
|
111
|
-
expect(
|
|
112
|
-
t('{0} is {1:c}', t('the "{0}" {1}', 'foo', 'attribute'), 'disallowed') +
|
|
113
|
-
t('. ') +
|
|
114
|
-
t('Did you mean "{0}"?', 'bar'),
|
|
115
|
-
).toBe('属性「foo」は許可されていません。「bar」ではありませんか?');
|
|
116
|
-
expect(
|
|
117
|
-
t(
|
|
118
|
-
'{0} must not be {1}',
|
|
119
|
-
t('{0} of {1}', t('the {0}', 'value'), t('the "{0}" {1}', 'foo', 'attribute')),
|
|
120
|
-
'empty string',
|
|
121
|
-
),
|
|
122
|
-
).toBe('属性「foo」の値は空文字にするべきではありません');
|
|
123
|
-
expect(
|
|
124
|
-
t(
|
|
125
|
-
'{0} expects {1}',
|
|
126
|
-
t('the "{0}" {1}', 'foo', 'attribute'),
|
|
127
|
-
t('{0} greater than {1}', 'floating-point number', 'zero'),
|
|
128
|
-
),
|
|
129
|
-
).toBe('属性「foo」にはゼロより大きい浮動小数点数が必要です');
|
|
130
|
-
expect(
|
|
131
|
-
t(
|
|
132
|
-
'{0} expects {1:c}',
|
|
133
|
-
t('the "{0}" {1}', 'foo', 'attribute'),
|
|
134
|
-
t('in the range between {0} and {1}', 'zero', 'one'),
|
|
135
|
-
),
|
|
136
|
-
).toBe('属性「foo」はゼロから1の範囲である必要があります');
|
|
137
|
-
expect(
|
|
138
|
-
t(
|
|
139
|
-
'{0} expects {1:c}',
|
|
140
|
-
t('the "{0}" {1}', 'foo', 'attribute'),
|
|
141
|
-
t(
|
|
142
|
-
'{0:c} and {1:c}',
|
|
143
|
-
t('{0} greater than {1}', 'non-negative integer', 'zero'),
|
|
144
|
-
t('less than or equal to {0}', 1000),
|
|
145
|
-
),
|
|
146
|
-
),
|
|
147
|
-
).toBe('属性「foo」はゼロより大きい正の整数且つ、1,000以下である必要があります');
|
|
148
|
-
expect(
|
|
149
|
-
t('{0} behaves the same as {1} if {2}', t('the "{0}" {1}', 'foo', 'attribute'), '-1', t('less than {0}', '-1')),
|
|
150
|
-
).toBe('属性「foo」は-1未満の場合、-1と同じ振る舞いをします');
|
|
151
|
-
expect(
|
|
152
|
-
t('{0} expects {1:c}', t('the "{0}" {1}', 'foo', 'attribute'), t('either {0}', t(['A', 'B', 'C', 'D']))),
|
|
153
|
-
).toBe('属性「foo」は「A」「B」「C」「D」のいずれかである必要があります');
|
|
154
|
-
expect(t('{0} expects {1:c}', t('the "{0}" {1}', 'foo', 'attribute'), t('valid {0}', 'hash-name reference'))).toBe(
|
|
155
|
-
'属性「foo」は妥当なハッシュ名参照である必要があります',
|
|
156
|
-
);
|
|
157
|
-
expect(t('{0} expects {1}', t('the "{0}" {1}', 'foo', 'attribute'), 'angle')).toBe('属性「foo」には角度が必要です');
|
|
158
|
-
expect(
|
|
159
|
-
t(
|
|
160
|
-
'{0} expects {1:c}',
|
|
161
|
-
t('the "{0}" {1}', 'foo', 'attribute'),
|
|
162
|
-
t('{0} as {1}', t('{0} to {1}', '0%', '100%'), 'alpha channel value'),
|
|
163
|
-
),
|
|
164
|
-
).toBe('属性「foo」は不透明度として0%から100%である必要があります');
|
|
165
|
-
expect(t('{0} should be {1}', t('the "{0}" {1}', 'foo', 'role'), 'top level')).toBe(
|
|
166
|
-
'ロール「foo」はトップレベルにしたほうがよいです',
|
|
167
|
-
);
|
|
168
|
-
expect(t('Require {0}', t('unique {0}', 'accessible name'))).toBe('一意のアクセシブルな名前が必要です');
|
|
169
|
-
expect(
|
|
170
|
-
t(
|
|
171
|
-
'{0} must be {1}',
|
|
172
|
-
t('the "{0}" {1}', 'foo', 'element'),
|
|
173
|
-
t('{0} of {1}', 'descendant', t('the "{0}" {1}', 'bar', 'element')),
|
|
174
|
-
),
|
|
175
|
-
).toBe('要素「foo」は要素「bar」の子孫にするべきです');
|
|
176
|
-
expect(
|
|
177
|
-
t(
|
|
178
|
-
'{0} according to {1}',
|
|
179
|
-
t(
|
|
180
|
-
'{0} is {1:c}',
|
|
181
|
-
t('{0} of {1}', t('the {0}', 'contents'), t('the "{0}" {1}', 'foo', 'element')),
|
|
182
|
-
'invalid',
|
|
183
|
-
),
|
|
184
|
-
'the html specification',
|
|
185
|
-
),
|
|
186
|
-
).toBe('HTMLの仕様において、要素「foo」の内容は妥当ではありません');
|
|
187
|
-
expect(t('{0} expects {1}', t('the "{0}" {1}', 'foo', 'attribute'), t('the "{0}" {1}', 'bar', 'element'))).toBe(
|
|
188
|
-
'属性「foo」には要素「bar」が必要です',
|
|
189
|
-
);
|
|
190
|
-
expect(t('Require {0}', t('the "{0}" {1}', 'h1', 'element'))).toBe('要素「h1」が必要です');
|
|
191
|
-
expect(t('{0} is {1:c}', t('the "{0}" {1}', 'h1', 'element'), 'duplicated')).toBe('要素「h1」が重複しています');
|
|
192
|
-
expect(
|
|
193
|
-
t(
|
|
194
|
-
'{0} according to {1}',
|
|
195
|
-
t('{0} does not exist', t('the "{0}" {1}', 'foo', 'role')),
|
|
196
|
-
'the WAI-ARIA specification',
|
|
197
|
-
),
|
|
198
|
-
).toBe('WAI-ARIAの仕様において、ロール「foo」は存在しません');
|
|
199
|
-
expect(t('{0} is {1}', t('the "{0}" {1}', 'foo', 'role'), 'the abstract role')).toBe(
|
|
200
|
-
'ロール「foo」は抽象ロールです',
|
|
201
|
-
);
|
|
202
|
-
expect(
|
|
203
|
-
t(
|
|
204
|
-
'{0} is {1}',
|
|
205
|
-
t('the "{0}" {1}', 'foo', 'role'),
|
|
206
|
-
t('{0} of {1}', 'the implicit role', t('the "{0}" {1}', 'bar', 'element')),
|
|
207
|
-
),
|
|
208
|
-
).toBe('ロール「foo」は要素「bar」の暗黙のロールです');
|
|
209
|
-
expect(
|
|
210
|
-
t(
|
|
211
|
-
'{0} according to {1}',
|
|
212
|
-
t('Cannot overwrite {0}', t('{0} of {1}', t('the {0}', 'role'), t('the "{0}" {1}', 'foo', 'element'))),
|
|
213
|
-
'ARIA in HTML specification',
|
|
214
|
-
),
|
|
215
|
-
).toBe('ARIA in HTMLの仕様において、要素「foo」のロールを上書きすることはできません');
|
|
216
|
-
expect(
|
|
217
|
-
t(
|
|
218
|
-
'{0} according to {1}',
|
|
219
|
-
t('Cannot overwrite {0} to {1}', t('the "{0}" {1}', 'foo', 'role'), t('the "{0}" {1}', 'bar', 'element')),
|
|
220
|
-
'ARIA in HTML specification',
|
|
221
|
-
),
|
|
222
|
-
).toBe('ARIA in HTMLの仕様において、ロール「foo」を要素「bar」に上書きすることはできません');
|
|
223
|
-
expect(
|
|
224
|
-
t(
|
|
225
|
-
'{0:c} on {1}',
|
|
226
|
-
t('{0} is {1:c}', t('the "{0}" {1}', 'foo', 'ARIA property'), 'deprecated'),
|
|
227
|
-
t('the "{0}" {1}', 'bar', 'role'),
|
|
228
|
-
),
|
|
229
|
-
).toBe('ロール「bar」では、ARIAプロパティ「foo」は非推奨です');
|
|
230
|
-
expect(
|
|
231
|
-
t(
|
|
232
|
-
'{0:c} on {1}',
|
|
233
|
-
t('{0} is {1:c}', t('the "{0}" {1}', 'foo', 'ARIA state'), 'disallowed'),
|
|
234
|
-
t('the "{0}" {1}', 'bar', 'role'),
|
|
235
|
-
),
|
|
236
|
-
).toBe('ロール「bar」では、ARIAステート「foo」は許可されていません');
|
|
237
|
-
expect(
|
|
238
|
-
t('{0:c} on {1}', t('Require {0}', t('the "{0}" {1}', 'foo', 'ARIA state')), t('the "{0}" {1}', 'bar', 'role')),
|
|
239
|
-
).toBe('ロール「bar」では、ARIAステート「foo」が必要です');
|
|
240
|
-
expect(t('{0} is not {1}', t('the "{0}" {1}', 'foo', 'ARIA property'), 'global property')).toBe(
|
|
241
|
-
'ARIAプロパティ「foo」はグローバルプロパティではありません',
|
|
242
|
-
);
|
|
243
|
-
expect(
|
|
244
|
-
t(
|
|
245
|
-
'{0} has {1}',
|
|
246
|
-
t('the "{0}" {1}', 'foo', 'ARIA property'),
|
|
247
|
-
t(
|
|
248
|
-
'the same {0} as {1}',
|
|
249
|
-
'semantics',
|
|
250
|
-
t(
|
|
251
|
-
'{0} or {1}',
|
|
252
|
-
t('the current "{0}" {1}', 'bar', 'attribute'),
|
|
253
|
-
t('the implicit "{0}" {1}', 'bar', 'attribute'),
|
|
254
|
-
),
|
|
255
|
-
),
|
|
256
|
-
),
|
|
257
|
-
).toBe('ARIAプロパティ「foo」は現在の属性「bar」もしくは暗黙の属性「bar」と同等のセマンティクスを持っています');
|
|
258
|
-
expect(
|
|
259
|
-
t(
|
|
260
|
-
'{0} contradicts {1}',
|
|
261
|
-
t('the "{0}" {1}', 'foo', 'ARIA state'),
|
|
262
|
-
t('the current "{0}" {1}', 'bar', 'attribute'),
|
|
263
|
-
),
|
|
264
|
-
).toBe('ARIAステート「foo」は現在の属性「bar」と矛盾しています');
|
|
265
|
-
expect(
|
|
266
|
-
t(
|
|
267
|
-
'{0} contradicts {1}',
|
|
268
|
-
t('the "{0}" {1}', 'foo', 'ARIA property'),
|
|
269
|
-
t('the implicit "{0}" {1}', 'bar', 'attribute'),
|
|
270
|
-
),
|
|
271
|
-
).toBe('ARIAプロパティ「foo」は暗黙の属性「bar」と矛盾しています');
|
|
272
|
-
expect(t('It is {0}', 'default value')).toBe('デフォルト値です');
|
|
273
|
-
});
|