UNPKG

3.98 kBJavaScriptView Raw
1// https://unicode-org.github.io/icu/userguide/format_parse/messages/
2// https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/com/ibm/icu/text/MessageFormat.html
3
4(function (Prism) {
5
6 /**
7 * @param {string} source
8 * @param {number} level
9 * @returns {string}
10 */
11 function nested(source, level) {
12 if (level <= 0) {
13 return /[]/.source;
14 } else {
15 return source.replace(/<SELF>/g, function () { return nested(source, level - 1); });
16 }
17 }
18
19 var stringPattern = /'[{}:=,](?:[^']|'')*'(?!')/;
20
21 var escape = {
22 pattern: /''/,
23 greedy: true,
24 alias: 'operator'
25 };
26 var string = {
27 pattern: stringPattern,
28 greedy: true,
29 inside: {
30 'escape': escape
31 }
32 };
33
34 var argumentSource = nested(
35 /\{(?:[^{}']|'(?![{},'])|''|<STR>|<SELF>)*\}/.source
36 .replace(/<STR>/g, function () { return stringPattern.source; }),
37 8
38 );
39
40 var nestedMessage = {
41 pattern: RegExp(argumentSource),
42 inside: {
43 'message': {
44 pattern: /^(\{)[\s\S]+(?=\}$)/,
45 lookbehind: true,
46 inside: null // see below
47 },
48 'message-delimiter': {
49 pattern: /./,
50 alias: 'punctuation'
51 }
52 }
53 };
54
55 Prism.languages['icu-message-format'] = {
56 'argument': {
57 pattern: RegExp(argumentSource),
58 greedy: true,
59 inside: {
60 'content': {
61 pattern: /^(\{)[\s\S]+(?=\}$)/,
62 lookbehind: true,
63 inside: {
64 'argument-name': {
65 pattern: /^(\s*)[^{}:=,\s]+/,
66 lookbehind: true
67 },
68 'choice-style': {
69 // https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1ChoiceFormat.html#details
70 pattern: /^(\s*,\s*choice\s*,\s*)\S(?:[\s\S]*\S)?/,
71 lookbehind: true,
72 inside: {
73 'punctuation': /\|/,
74 'range': {
75 pattern: /^(\s*)[+-]?(?:\d+(?:\.\d*)?|\u221e)\s*[<#\u2264]/,
76 lookbehind: true,
77 inside: {
78 'operator': /[<#\u2264]/,
79 'number': /\S+/
80 }
81 },
82 rest: null // see below
83 }
84 },
85 'plural-style': {
86 // https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/com/ibm/icu/text/PluralFormat.html#:~:text=Patterns%20and%20Their%20Interpretation
87 pattern: /^(\s*,\s*(?:plural|selectordinal)\s*,\s*)\S(?:[\s\S]*\S)?/,
88 lookbehind: true,
89 inside: {
90 'offset': /^offset:\s*\d+/,
91 'nested-message': nestedMessage,
92 'selector': {
93 pattern: /=\d+|[^{}:=,\s]+/,
94 inside: {
95 'keyword': /^(?:few|many|one|other|two|zero)$/
96 }
97 }
98 }
99 },
100 'select-style': {
101 // https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/com/ibm/icu/text/SelectFormat.html#:~:text=Patterns%20and%20Their%20Interpretation
102 pattern: /^(\s*,\s*select\s*,\s*)\S(?:[\s\S]*\S)?/,
103 lookbehind: true,
104 inside: {
105 'nested-message': nestedMessage,
106 'selector': {
107 pattern: /[^{}:=,\s]+/,
108 inside: {
109 'keyword': /^other$/
110 }
111 }
112 }
113 },
114 'keyword': /\b(?:choice|plural|select|selectordinal)\b/,
115 'arg-type': {
116 pattern: /\b(?:date|duration|number|ordinal|spellout|time)\b/,
117 alias: 'keyword'
118 },
119 'arg-skeleton': {
120 pattern: /(,\s*)::[^{}:=,\s]+/,
121 lookbehind: true
122 },
123 'arg-style': {
124 pattern: /(,\s*)(?:currency|full|integer|long|medium|percent|short)(?=\s*$)/,
125 lookbehind: true
126 },
127 'arg-style-text': {
128 pattern: RegExp(/(^\s*,\s*(?=\S))/.source + nested(/(?:[^{}']|'[^']*'|\{(?:<SELF>)?\})+/.source, 8) + '$'),
129 lookbehind: true,
130 alias: 'string'
131 },
132 'punctuation': /,/
133 }
134 },
135 'argument-delimiter': {
136 pattern: /./,
137 alias: 'operator'
138 }
139 }
140 },
141 'escape': escape,
142 'string': string
143 };
144
145 nestedMessage.inside.message.inside = Prism.languages['icu-message-format'];
146 Prism.languages['icu-message-format'].argument.inside.content.inside['choice-style'].inside.rest = Prism.languages['icu-message-format'];
147
148}(Prism));