summaryrefslogtreecommitdiffstats
path: root/public/prism/prism-protobuf.js
blob: 949ef3adc317b6ba87549128c1d52555cb87fba1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
(function (Prism) {
  var builtinTypes =
    /\b(?:bool|bytes|double|s?fixed(?:32|64)|float|[su]?int(?:32|64)|string)\b/;

  Prism.languages.protobuf = Prism.languages.extend('clike', {
    'class-name': [
      {
        pattern: /(\b(?:enum|extend|message|service)\s+)[A-Za-z_]\w*(?=\s*\{)/,
        lookbehind: true,
      },
      {
        pattern:
          /(\b(?:rpc\s+\w+|returns)\s*\(\s*(?:stream\s+)?)\.?[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*(?=\s*\))/,
        lookbehind: true,
      },
    ],
    keyword:
      /\b(?:enum|extend|extensions|import|message|oneof|option|optional|package|public|repeated|required|reserved|returns|rpc(?=\s+\w)|service|stream|syntax|to)\b(?!\s*=\s*\d)/,
    function: /\b[a-z_]\w*(?=\s*\()/i,
  });

  Prism.languages.insertBefore('protobuf', 'operator', {
    map: {
      pattern: /\bmap<\s*[\w.]+\s*,\s*[\w.]+\s*>(?=\s+[a-z_]\w*\s*[=;])/i,
      alias: 'class-name',
      inside: {
        punctuation: /[<>.,]/,
        builtin: builtinTypes,
      },
    },
    builtin: builtinTypes,
    'positional-class-name': {
      pattern: /(?:\b|\B\.)[a-z_]\w*(?:\.[a-z_]\w*)*(?=\s+[a-z_]\w*\s*[=;])/i,
      alias: 'class-name',
      inside: {
        punctuation: /\./,
      },
    },
    annotation: {
      pattern: /(\[\s*)[a-z_]\w*(?=\s*=)/i,
      lookbehind: true,
    },
  });
})(Prism);
n>alias: 'selector', }, { pattern: /([\t ])\S+/, lookbehind: true, greedy: true, alias: 'operator', }, { pattern: /\S(?:.*\S)?/, alias: 'operator', }, ], }; Prism.languages.naniscript = { // ; ... comment: { pattern: /^([\t ]*);.*/m, lookbehind: true, }, // > ... // Define is a control line starting with '>' followed by a word, a space and a text. define: { pattern: /^>.+/m, alias: 'tag', inside: { value: { pattern: /(^>\w+[\t ]+)(?!\s)[^{}\r\n]+/, lookbehind: true, alias: 'operator', }, key: { pattern: /(^>)\w+/, lookbehind: true, }, }, }, // # ... label: { pattern: /^([\t ]*)#[\t ]*\w+[\t ]*$/m, lookbehind: true, alias: 'regex', }, command: { pattern: /^([\t ]*)@\w+(?=[\t ]|$).*/m, lookbehind: true, alias: 'function', inside: { 'command-name': /^@\w+/, expression: { pattern: expressionDef, greedy: true, alias: 'selector', }, 'command-params': { pattern: /\s*\S[\s\S]*/, inside: params, }, }, }, // Generic is any line that doesn't start with operators: ;>#@ 'generic-text': { pattern: /(^[ \t]*)[^#@>;\s].*/m, lookbehind: true, alias: 'punctuation', inside: { // \{ ... \} ... \[ ... \] ... \" 'escaped-char': /\\[{}\[\]"]/, expression: { pattern: expressionDef, greedy: true, alias: 'selector', }, 'inline-command': { pattern: /\[[\t ]*\w[^\r\n\[\]]*\]/, greedy: true, alias: 'function', inside: { 'command-params': { pattern: /(^\[[\t ]*\w+\b)[\s\S]+(?=\]$)/, lookbehind: true, inside: params, }, 'command-param-name': { pattern: /^(\[[\t ]*)\w+/, lookbehind: true, alias: 'name', }, 'start-stop-char': /[\[\]]/, }, }, }, }, }; Prism.languages.nani = Prism.languages['naniscript']; /** @typedef {InstanceType<import("./prism-core")["Token"]>} Token */ /** * This hook is used to validate generic-text tokens for balanced brackets. * Mark token as bad-line when contains not balanced brackets: {},[] */ Prism.hooks.add('after-tokenize', function (env) { /** @type {(Token | string)[]} */ var tokens = env.tokens; tokens.forEach(function (token) { if (typeof token !== 'string' && token.type === 'generic-text') { var content = getTextContent(token); if (!isBracketsBalanced(content)) { token.type = 'bad-line'; token.content = content; } } }); }); /** * @param {string} input * @returns {boolean} */ function isBracketsBalanced(input) { var brackets = '[]{}'; var stack = []; for (var i = 0; i < input.length; i++) { var bracket = input[i]; var bracketsIndex = brackets.indexOf(bracket); if (bracketsIndex !== -1) { if (bracketsIndex % 2 === 0) { stack.push(bracketsIndex + 1); } else if (stack.pop() !== bracketsIndex) { return false; } } } return stack.length === 0; } /** * @param {string | Token | (string | Token)[]} token * @returns {string} */ function getTextContent(token) { if (typeof token === 'string') { return token; } else if (Array.isArray(token)) { return token.map(getTextContent).join(''); } else { return getTextContent(token.content); } } })(Prism);