123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- // https://unicode-org.github.io/icu/userguide/format_parse/messages/
- // https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/com/ibm/icu/text/MessageFormat.html
- (function (Prism) {
- /**
- * @param {string} source
- * @param {number} level
- * @returns {string}
- */
- function nested(source, level) {
- if (level <= 0) {
- return /[]/.source;
- } else {
- return source.replace(/<SELF>/g, function () { return nested(source, level - 1); });
- }
- }
- var stringPattern = /'[{}:=,](?:[^']|'')*'(?!')/;
- var escape = {
- pattern: /''/,
- greedy: true,
- alias: 'operator'
- };
- var string = {
- pattern: stringPattern,
- greedy: true,
- inside: {
- 'escape': escape
- }
- };
- var argumentSource = nested(
- /\{(?:[^{}']|'(?![{},'])|''|<STR>|<SELF>)*\}/.source
- .replace(/<STR>/g, function () { return stringPattern.source; }),
- 8
- );
- var nestedMessage = {
- pattern: RegExp(argumentSource),
- inside: {
- 'message': {
- pattern: /^(\{)[\s\S]+(?=\}$)/,
- lookbehind: true,
- inside: null // see below
- },
- 'message-delimiter': {
- pattern: /./,
- alias: 'punctuation'
- }
- }
- };
- Prism.languages['icu-message-format'] = {
- 'argument': {
- pattern: RegExp(argumentSource),
- greedy: true,
- inside: {
- 'content': {
- pattern: /^(\{)[\s\S]+(?=\}$)/,
- lookbehind: true,
- inside: {
- 'argument-name': {
- pattern: /^(\s*)[^{}:=,\s]+/,
- lookbehind: true
- },
- 'choice-style': {
- // https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1ChoiceFormat.html#details
- pattern: /^(\s*,\s*choice\s*,\s*)\S(?:[\s\S]*\S)?/,
- lookbehind: true,
- inside: {
- 'punctuation': /\|/,
- 'range': {
- pattern: /^(\s*)[+-]?(?:\d+(?:\.\d*)?|\u221e)\s*[<#\u2264]/,
- lookbehind: true,
- inside: {
- 'operator': /[<#\u2264]/,
- 'number': /\S+/
- }
- },
- rest: null // see below
- }
- },
- 'plural-style': {
- // https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/com/ibm/icu/text/PluralFormat.html#:~:text=Patterns%20and%20Their%20Interpretation
- pattern: /^(\s*,\s*(?:plural|selectordinal)\s*,\s*)\S(?:[\s\S]*\S)?/,
- lookbehind: true,
- inside: {
- 'offset': /^offset:\s*\d+/,
- 'nested-message': nestedMessage,
- 'selector': {
- pattern: /=\d+|[^{}:=,\s]+/,
- inside: {
- 'keyword': /^(?:few|many|one|other|two|zero)$/
- }
- }
- }
- },
- 'select-style': {
- // https://unicode-org.github.io/icu-docs/apidoc/released/icu4j/com/ibm/icu/text/SelectFormat.html#:~:text=Patterns%20and%20Their%20Interpretation
- pattern: /^(\s*,\s*select\s*,\s*)\S(?:[\s\S]*\S)?/,
- lookbehind: true,
- inside: {
- 'nested-message': nestedMessage,
- 'selector': {
- pattern: /[^{}:=,\s]+/,
- inside: {
- 'keyword': /^other$/
- }
- }
- }
- },
- 'keyword': /\b(?:choice|plural|select|selectordinal)\b/,
- 'arg-type': {
- pattern: /\b(?:date|duration|number|ordinal|spellout|time)\b/,
- alias: 'keyword'
- },
- 'arg-skeleton': {
- pattern: /(,\s*)::[^{}:=,\s]+/,
- lookbehind: true
- },
- 'arg-style': {
- pattern: /(,\s*)(?:currency|full|integer|long|medium|percent|short)(?=\s*$)/,
- lookbehind: true
- },
- 'arg-style-text': {
- pattern: RegExp(/(^\s*,\s*(?=\S))/.source + nested(/(?:[^{}']|'[^']*'|\{(?:<SELF>)?\})+/.source, 8) + '$'),
- lookbehind: true,
- alias: 'string'
- },
- 'punctuation': /,/
- }
- },
- 'argument-delimiter': {
- pattern: /./,
- alias: 'operator'
- }
- }
- },
- 'escape': escape,
- 'string': string
- };
- nestedMessage.inside.message.inside = Prism.languages['icu-message-format'];
- Prism.languages['icu-message-format'].argument.inside.content.inside['choice-style'].inside.rest = Prism.languages['icu-message-format'];
- }(Prism));
|