1 | (function (Prism) {
|
2 |
|
3 | var expressionDef = /\{[^\r\n\[\]{}]*\}/;
|
4 |
|
5 | var params = {
|
6 | 'quoted-string': {
|
7 | pattern: /"(?:[^"\\]|\\.)*"/,
|
8 | alias: 'operator'
|
9 | },
|
10 | 'command-param-id': {
|
11 | pattern: /(\s)\w+:/,
|
12 | lookbehind: true,
|
13 | alias: 'property'
|
14 | },
|
15 | 'command-param-value': [
|
16 | {
|
17 | pattern: expressionDef,
|
18 | alias: 'selector',
|
19 | },
|
20 | {
|
21 | pattern: /([\t ])\S+/,
|
22 | lookbehind: true,
|
23 | greedy: true,
|
24 | alias: 'operator',
|
25 | },
|
26 | {
|
27 | pattern: /\S(?:.*\S)?/,
|
28 | alias: 'operator',
|
29 | }
|
30 | ]
|
31 | };
|
32 |
|
33 | Prism.languages.naniscript = {
|
34 |
|
35 | 'comment': {
|
36 | pattern: /^([\t ]*);.*/m,
|
37 | lookbehind: true,
|
38 | },
|
39 |
|
40 |
|
41 | 'define': {
|
42 | pattern: /^>.+/m,
|
43 | alias: 'tag',
|
44 | inside: {
|
45 | 'value': {
|
46 | pattern: /(^>\w+[\t ]+)(?!\s)[^{}\r\n]+/,
|
47 | lookbehind: true,
|
48 | alias: 'operator'
|
49 | },
|
50 | 'key': {
|
51 | pattern: /(^>)\w+/,
|
52 | lookbehind: true,
|
53 | }
|
54 | }
|
55 | },
|
56 |
|
57 | 'label': {
|
58 | pattern: /^([\t ]*)#[\t ]*\w+[\t ]*$/m,
|
59 | lookbehind: true,
|
60 | alias: 'regex'
|
61 | },
|
62 | 'command': {
|
63 | pattern: /^([\t ]*)@\w+(?=[\t ]|$).*/m,
|
64 | lookbehind: true,
|
65 | alias: 'function',
|
66 | inside: {
|
67 | 'command-name': /^@\w+/,
|
68 | 'expression': {
|
69 | pattern: expressionDef,
|
70 | greedy: true,
|
71 | alias: 'selector'
|
72 | },
|
73 | 'command-params': {
|
74 | pattern: /\s*\S[\s\S]*/,
|
75 | inside: params
|
76 | },
|
77 | }
|
78 | },
|
79 |
|
80 | 'generic-text': {
|
81 | pattern: /(^[ \t]*)[^#@>;\s].*/m,
|
82 | lookbehind: true,
|
83 | alias: 'punctuation',
|
84 | inside: {
|
85 |
|
86 | 'escaped-char': /\\[{}\[\]"]/,
|
87 | 'expression': {
|
88 | pattern: expressionDef,
|
89 | greedy: true,
|
90 | alias: 'selector'
|
91 | },
|
92 | 'inline-command': {
|
93 | pattern: /\[[\t ]*\w[^\r\n\[\]]*\]/,
|
94 | greedy: true,
|
95 | alias: 'function',
|
96 | inside: {
|
97 | 'command-params': {
|
98 | pattern: /(^\[[\t ]*\w+\b)[\s\S]+(?=\]$)/,
|
99 | lookbehind: true,
|
100 | inside: params
|
101 | },
|
102 | 'command-param-name': {
|
103 | pattern: /^(\[[\t ]*)\w+/,
|
104 | lookbehind: true,
|
105 | alias: 'name',
|
106 | },
|
107 | 'start-stop-char': /[\[\]]/,
|
108 | }
|
109 | },
|
110 | }
|
111 | }
|
112 | };
|
113 | Prism.languages.nani = Prism.languages['naniscript'];
|
114 |
|
115 |
|
116 |
|
117 | |
118 |
|
119 |
|
120 |
|
121 | Prism.hooks.add('after-tokenize', function (env) {
|
122 |
|
123 | var tokens = env.tokens;
|
124 | tokens.forEach(function (token) {
|
125 | if (typeof token !== 'string' && token.type === 'generic-text') {
|
126 | var content = getTextContent(token);
|
127 | if (!isBracketsBalanced(content)) {
|
128 | token.type = 'bad-line';
|
129 | token.content = content;
|
130 | }
|
131 | }
|
132 | });
|
133 | });
|
134 |
|
135 | |
136 |
|
137 |
|
138 |
|
139 | function isBracketsBalanced(input) {
|
140 | var brackets = '[]{}';
|
141 | var stack = [];
|
142 | for (var i = 0; i < input.length; i++) {
|
143 | var bracket = input[i];
|
144 | var bracketsIndex = brackets.indexOf(bracket);
|
145 | if (bracketsIndex !== -1) {
|
146 | if (bracketsIndex % 2 === 0) {
|
147 | stack.push(bracketsIndex + 1);
|
148 | } else if (stack.pop() !== bracketsIndex) {
|
149 | return false;
|
150 | }
|
151 | }
|
152 | }
|
153 | return stack.length === 0;
|
154 | }
|
155 |
|
156 | |
157 |
|
158 |
|
159 |
|
160 | function getTextContent(token) {
|
161 | if (typeof token === 'string') {
|
162 | return token;
|
163 | } else if (Array.isArray(token)) {
|
164 | return token.map(getTextContent).join('');
|
165 | } else {
|
166 | return getTextContent(token.content);
|
167 | }
|
168 | }
|
169 |
|
170 | }(Prism));
|