Mercurial
comparison .cms/lib/codemirror/mode/rst/rst.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE | |
3 | |
4 (function(mod) { | |
5 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
6 mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay")); | |
7 else if (typeof define == "function" && define.amd) // AMD | |
8 define(["../../lib/codemirror", "../python/python", "../stex/stex", "../../addon/mode/overlay"], mod); | |
9 else // Plain browser env | |
10 mod(CodeMirror); | |
11 })(function(CodeMirror) { | |
12 "use strict"; | |
13 | |
14 CodeMirror.defineMode('rst', function (config, options) { | |
15 | |
16 var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/; | |
17 var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/; | |
18 var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/; | |
19 | |
20 var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/; | |
21 var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/; | |
22 var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/; | |
23 | |
24 var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://"; | |
25 var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})"; | |
26 var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*"; | |
27 var rx_uri = new RegExp("^" + rx_uri_protocol + rx_uri_domain + rx_uri_path); | |
28 | |
29 var overlay = { | |
30 token: function (stream) { | |
31 | |
32 if (stream.match(rx_strong) && stream.match (/\W+|$/, false)) | |
33 return 'strong'; | |
34 if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false)) | |
35 return 'em'; | |
36 if (stream.match(rx_literal) && stream.match (/\W+|$/, false)) | |
37 return 'string-2'; | |
38 if (stream.match(rx_number)) | |
39 return 'number'; | |
40 if (stream.match(rx_positive)) | |
41 return 'positive'; | |
42 if (stream.match(rx_negative)) | |
43 return 'negative'; | |
44 if (stream.match(rx_uri)) | |
45 return 'link'; | |
46 | |
47 while (stream.next() != null) { | |
48 if (stream.match(rx_strong, false)) break; | |
49 if (stream.match(rx_emphasis, false)) break; | |
50 if (stream.match(rx_literal, false)) break; | |
51 if (stream.match(rx_number, false)) break; | |
52 if (stream.match(rx_positive, false)) break; | |
53 if (stream.match(rx_negative, false)) break; | |
54 if (stream.match(rx_uri, false)) break; | |
55 } | |
56 | |
57 return null; | |
58 } | |
59 }; | |
60 | |
61 var mode = CodeMirror.getMode( | |
62 config, options.backdrop || 'rst-base' | |
63 ); | |
64 | |
65 return CodeMirror.overlayMode(mode, overlay, true); // combine | |
66 }, 'python', 'stex'); | |
67 | |
68 /////////////////////////////////////////////////////////////////////////////// | |
69 /////////////////////////////////////////////////////////////////////////////// | |
70 | |
71 CodeMirror.defineMode('rst-base', function (config) { | |
72 | |
73 /////////////////////////////////////////////////////////////////////////// | |
74 /////////////////////////////////////////////////////////////////////////// | |
75 | |
76 function format(string) { | |
77 var args = Array.prototype.slice.call(arguments, 1); | |
78 return string.replace(/{(\d+)}/g, function (match, n) { | |
79 return typeof args[n] != 'undefined' ? args[n] : match; | |
80 }); | |
81 } | |
82 | |
83 /////////////////////////////////////////////////////////////////////////// | |
84 /////////////////////////////////////////////////////////////////////////// | |
85 | |
86 var mode_python = CodeMirror.getMode(config, 'python'); | |
87 var mode_stex = CodeMirror.getMode(config, 'stex'); | |
88 | |
89 /////////////////////////////////////////////////////////////////////////// | |
90 /////////////////////////////////////////////////////////////////////////// | |
91 | |
92 var SEPA = "\\s+"; | |
93 var TAIL = "(?:\\s*|\\W|$)", | |
94 rx_TAIL = new RegExp(format('^{0}', TAIL)); | |
95 | |
96 var NAME = | |
97 "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)", | |
98 rx_NAME = new RegExp(format('^{0}', NAME)); | |
99 var NAME_WWS = | |
100 "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)"; | |
101 var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS); | |
102 | |
103 var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)"; | |
104 var TEXT2 = "(?:[^\\`]+)", | |
105 rx_TEXT2 = new RegExp(format('^{0}', TEXT2)); | |
106 | |
107 var rx_section = new RegExp( | |
108 "^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$"); | |
109 var rx_explicit = new RegExp( | |
110 format('^\\.\\.{0}', SEPA)); | |
111 var rx_link = new RegExp( | |
112 format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL)); | |
113 var rx_directive = new RegExp( | |
114 format('^{0}::{1}', REF_NAME, TAIL)); | |
115 var rx_substitution = new RegExp( | |
116 format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL)); | |
117 var rx_footnote = new RegExp( | |
118 format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL)); | |
119 var rx_citation = new RegExp( | |
120 format('^\\[{0}\\]{1}', REF_NAME, TAIL)); | |
121 | |
122 var rx_substitution_ref = new RegExp( | |
123 format('^\\|{0}\\|', TEXT1)); | |
124 var rx_footnote_ref = new RegExp( | |
125 format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME)); | |
126 var rx_citation_ref = new RegExp( | |
127 format('^\\[{0}\\]_', REF_NAME)); | |
128 var rx_link_ref1 = new RegExp( | |
129 format('^{0}__?', REF_NAME)); | |
130 var rx_link_ref2 = new RegExp( | |
131 format('^`{0}`_', TEXT2)); | |
132 | |
133 var rx_role_pre = new RegExp( | |
134 format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL)); | |
135 var rx_role_suf = new RegExp( | |
136 format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL)); | |
137 var rx_role = new RegExp( | |
138 format('^:{0}:{1}', NAME, TAIL)); | |
139 | |
140 var rx_directive_name = new RegExp(format('^{0}', REF_NAME)); | |
141 var rx_directive_tail = new RegExp(format('^::{0}', TAIL)); | |
142 var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1)); | |
143 var rx_substitution_sepa = new RegExp(format('^{0}', SEPA)); | |
144 var rx_substitution_name = new RegExp(format('^{0}', REF_NAME)); | |
145 var rx_substitution_tail = new RegExp(format('^::{0}', TAIL)); | |
146 var rx_link_head = new RegExp("^_"); | |
147 var rx_link_name = new RegExp(format('^{0}|_', REF_NAME)); | |
148 var rx_link_tail = new RegExp(format('^:{0}', TAIL)); | |
149 | |
150 var rx_verbatim = new RegExp('^::\\s*$'); | |
151 var rx_examples = new RegExp('^\\s+(?:>>>|In \\[\\d+\\]:)\\s'); | |
152 | |
153 /////////////////////////////////////////////////////////////////////////// | |
154 /////////////////////////////////////////////////////////////////////////// | |
155 | |
156 function to_normal(stream, state) { | |
157 var token = null; | |
158 | |
159 if (stream.sol() && stream.match(rx_examples, false)) { | |
160 change(state, to_mode, { | |
161 mode: mode_python, local: CodeMirror.startState(mode_python) | |
162 }); | |
163 } else if (stream.sol() && stream.match(rx_explicit)) { | |
164 change(state, to_explicit); | |
165 token = 'meta'; | |
166 } else if (stream.sol() && stream.match(rx_section)) { | |
167 change(state, to_normal); | |
168 token = 'header'; | |
169 } else if (phase(state) == rx_role_pre || | |
170 stream.match(rx_role_pre, false)) { | |
171 | |
172 switch (stage(state)) { | |
173 case 0: | |
174 change(state, to_normal, context(rx_role_pre, 1)); | |
175 stream.match(/^:/); | |
176 token = 'meta'; | |
177 break; | |
178 case 1: | |
179 change(state, to_normal, context(rx_role_pre, 2)); | |
180 stream.match(rx_NAME); | |
181 token = 'keyword'; | |
182 | |
183 if (stream.current().match(/^(?:math|latex)/)) { | |
184 state.tmp_stex = true; | |
185 } | |
186 break; | |
187 case 2: | |
188 change(state, to_normal, context(rx_role_pre, 3)); | |
189 stream.match(/^:`/); | |
190 token = 'meta'; | |
191 break; | |
192 case 3: | |
193 if (state.tmp_stex) { | |
194 state.tmp_stex = undefined; state.tmp = { | |
195 mode: mode_stex, local: CodeMirror.startState(mode_stex) | |
196 }; | |
197 } | |
198 | |
199 if (state.tmp) { | |
200 if (stream.peek() == '`') { | |
201 change(state, to_normal, context(rx_role_pre, 4)); | |
202 state.tmp = undefined; | |
203 break; | |
204 } | |
205 | |
206 token = state.tmp.mode.token(stream, state.tmp.local); | |
207 break; | |
208 } | |
209 | |
210 change(state, to_normal, context(rx_role_pre, 4)); | |
211 stream.match(rx_TEXT2); | |
212 token = 'string'; | |
213 break; | |
214 case 4: | |
215 change(state, to_normal, context(rx_role_pre, 5)); | |
216 stream.match(/^`/); | |
217 token = 'meta'; | |
218 break; | |
219 case 5: | |
220 change(state, to_normal, context(rx_role_pre, 6)); | |
221 stream.match(rx_TAIL); | |
222 break; | |
223 default: | |
224 change(state, to_normal); | |
225 } | |
226 } else if (phase(state) == rx_role_suf || | |
227 stream.match(rx_role_suf, false)) { | |
228 | |
229 switch (stage(state)) { | |
230 case 0: | |
231 change(state, to_normal, context(rx_role_suf, 1)); | |
232 stream.match(/^`/); | |
233 token = 'meta'; | |
234 break; | |
235 case 1: | |
236 change(state, to_normal, context(rx_role_suf, 2)); | |
237 stream.match(rx_TEXT2); | |
238 token = 'string'; | |
239 break; | |
240 case 2: | |
241 change(state, to_normal, context(rx_role_suf, 3)); | |
242 stream.match(/^`:/); | |
243 token = 'meta'; | |
244 break; | |
245 case 3: | |
246 change(state, to_normal, context(rx_role_suf, 4)); | |
247 stream.match(rx_NAME); | |
248 token = 'keyword'; | |
249 break; | |
250 case 4: | |
251 change(state, to_normal, context(rx_role_suf, 5)); | |
252 stream.match(/^:/); | |
253 token = 'meta'; | |
254 break; | |
255 case 5: | |
256 change(state, to_normal, context(rx_role_suf, 6)); | |
257 stream.match(rx_TAIL); | |
258 break; | |
259 default: | |
260 change(state, to_normal); | |
261 } | |
262 } else if (phase(state) == rx_role || stream.match(rx_role, false)) { | |
263 | |
264 switch (stage(state)) { | |
265 case 0: | |
266 change(state, to_normal, context(rx_role, 1)); | |
267 stream.match(/^:/); | |
268 token = 'meta'; | |
269 break; | |
270 case 1: | |
271 change(state, to_normal, context(rx_role, 2)); | |
272 stream.match(rx_NAME); | |
273 token = 'keyword'; | |
274 break; | |
275 case 2: | |
276 change(state, to_normal, context(rx_role, 3)); | |
277 stream.match(/^:/); | |
278 token = 'meta'; | |
279 break; | |
280 case 3: | |
281 change(state, to_normal, context(rx_role, 4)); | |
282 stream.match(rx_TAIL); | |
283 break; | |
284 default: | |
285 change(state, to_normal); | |
286 } | |
287 } else if (phase(state) == rx_substitution_ref || | |
288 stream.match(rx_substitution_ref, false)) { | |
289 | |
290 switch (stage(state)) { | |
291 case 0: | |
292 change(state, to_normal, context(rx_substitution_ref, 1)); | |
293 stream.match(rx_substitution_text); | |
294 token = 'variable-2'; | |
295 break; | |
296 case 1: | |
297 change(state, to_normal, context(rx_substitution_ref, 2)); | |
298 if (stream.match(/^_?_?/)) token = 'link'; | |
299 break; | |
300 default: | |
301 change(state, to_normal); | |
302 } | |
303 } else if (stream.match(rx_footnote_ref)) { | |
304 change(state, to_normal); | |
305 token = 'quote'; | |
306 } else if (stream.match(rx_citation_ref)) { | |
307 change(state, to_normal); | |
308 token = 'quote'; | |
309 } else if (stream.match(rx_link_ref1)) { | |
310 change(state, to_normal); | |
311 if (!stream.peek() || stream.peek().match(/^\W$/)) { | |
312 token = 'link'; | |
313 } | |
314 } else if (phase(state) == rx_link_ref2 || | |
315 stream.match(rx_link_ref2, false)) { | |
316 | |
317 switch (stage(state)) { | |
318 case 0: | |
319 if (!stream.peek() || stream.peek().match(/^\W$/)) { | |
320 change(state, to_normal, context(rx_link_ref2, 1)); | |
321 } else { | |
322 stream.match(rx_link_ref2); | |
323 } | |
324 break; | |
325 case 1: | |
326 change(state, to_normal, context(rx_link_ref2, 2)); | |
327 stream.match(/^`/); | |
328 token = 'link'; | |
329 break; | |
330 case 2: | |
331 change(state, to_normal, context(rx_link_ref2, 3)); | |
332 stream.match(rx_TEXT2); | |
333 break; | |
334 case 3: | |
335 change(state, to_normal, context(rx_link_ref2, 4)); | |
336 stream.match(/^`_/); | |
337 token = 'link'; | |
338 break; | |
339 default: | |
340 change(state, to_normal); | |
341 } | |
342 } else if (stream.match(rx_verbatim)) { | |
343 change(state, to_verbatim); | |
344 } | |
345 | |
346 else { | |
347 if (stream.next()) change(state, to_normal); | |
348 } | |
349 | |
350 return token; | |
351 } | |
352 | |
353 /////////////////////////////////////////////////////////////////////////// | |
354 /////////////////////////////////////////////////////////////////////////// | |
355 | |
356 function to_explicit(stream, state) { | |
357 var token = null; | |
358 | |
359 if (phase(state) == rx_substitution || | |
360 stream.match(rx_substitution, false)) { | |
361 | |
362 switch (stage(state)) { | |
363 case 0: | |
364 change(state, to_explicit, context(rx_substitution, 1)); | |
365 stream.match(rx_substitution_text); | |
366 token = 'variable-2'; | |
367 break; | |
368 case 1: | |
369 change(state, to_explicit, context(rx_substitution, 2)); | |
370 stream.match(rx_substitution_sepa); | |
371 break; | |
372 case 2: | |
373 change(state, to_explicit, context(rx_substitution, 3)); | |
374 stream.match(rx_substitution_name); | |
375 token = 'keyword'; | |
376 break; | |
377 case 3: | |
378 change(state, to_explicit, context(rx_substitution, 4)); | |
379 stream.match(rx_substitution_tail); | |
380 token = 'meta'; | |
381 break; | |
382 default: | |
383 change(state, to_normal); | |
384 } | |
385 } else if (phase(state) == rx_directive || | |
386 stream.match(rx_directive, false)) { | |
387 | |
388 switch (stage(state)) { | |
389 case 0: | |
390 change(state, to_explicit, context(rx_directive, 1)); | |
391 stream.match(rx_directive_name); | |
392 token = 'keyword'; | |
393 | |
394 if (stream.current().match(/^(?:math|latex)/)) | |
395 state.tmp_stex = true; | |
396 else if (stream.current().match(/^python/)) | |
397 state.tmp_py = true; | |
398 break; | |
399 case 1: | |
400 change(state, to_explicit, context(rx_directive, 2)); | |
401 stream.match(rx_directive_tail); | |
402 token = 'meta'; | |
403 | |
404 if (stream.match(/^latex\s*$/) || state.tmp_stex) { | |
405 state.tmp_stex = undefined; change(state, to_mode, { | |
406 mode: mode_stex, local: CodeMirror.startState(mode_stex) | |
407 }); | |
408 } | |
409 break; | |
410 case 2: | |
411 change(state, to_explicit, context(rx_directive, 3)); | |
412 if (stream.match(/^python\s*$/) || state.tmp_py) { | |
413 state.tmp_py = undefined; change(state, to_mode, { | |
414 mode: mode_python, local: CodeMirror.startState(mode_python) | |
415 }); | |
416 } | |
417 break; | |
418 default: | |
419 change(state, to_normal); | |
420 } | |
421 } else if (phase(state) == rx_link || stream.match(rx_link, false)) { | |
422 | |
423 switch (stage(state)) { | |
424 case 0: | |
425 change(state, to_explicit, context(rx_link, 1)); | |
426 stream.match(rx_link_head); | |
427 stream.match(rx_link_name); | |
428 token = 'link'; | |
429 break; | |
430 case 1: | |
431 change(state, to_explicit, context(rx_link, 2)); | |
432 stream.match(rx_link_tail); | |
433 token = 'meta'; | |
434 break; | |
435 default: | |
436 change(state, to_normal); | |
437 } | |
438 } else if (stream.match(rx_footnote)) { | |
439 change(state, to_normal); | |
440 token = 'quote'; | |
441 } else if (stream.match(rx_citation)) { | |
442 change(state, to_normal); | |
443 token = 'quote'; | |
444 } | |
445 | |
446 else { | |
447 stream.eatSpace(); | |
448 if (stream.eol()) { | |
449 change(state, to_normal); | |
450 } else { | |
451 stream.skipToEnd(); | |
452 change(state, to_comment); | |
453 token = 'comment'; | |
454 } | |
455 } | |
456 | |
457 return token; | |
458 } | |
459 | |
460 /////////////////////////////////////////////////////////////////////////// | |
461 /////////////////////////////////////////////////////////////////////////// | |
462 | |
463 function to_comment(stream, state) { | |
464 return as_block(stream, state, 'comment'); | |
465 } | |
466 | |
467 function to_verbatim(stream, state) { | |
468 return as_block(stream, state, 'meta'); | |
469 } | |
470 | |
471 function as_block(stream, state, token) { | |
472 if (stream.eol() || stream.eatSpace()) { | |
473 stream.skipToEnd(); | |
474 return token; | |
475 } else { | |
476 change(state, to_normal); | |
477 return null; | |
478 } | |
479 } | |
480 | |
481 /////////////////////////////////////////////////////////////////////////// | |
482 /////////////////////////////////////////////////////////////////////////// | |
483 | |
484 function to_mode(stream, state) { | |
485 | |
486 if (state.ctx.mode && state.ctx.local) { | |
487 | |
488 if (stream.sol()) { | |
489 if (!stream.eatSpace()) change(state, to_normal); | |
490 return null; | |
491 } | |
492 | |
493 return state.ctx.mode.token(stream, state.ctx.local); | |
494 } | |
495 | |
496 change(state, to_normal); | |
497 return null; | |
498 } | |
499 | |
500 /////////////////////////////////////////////////////////////////////////// | |
501 /////////////////////////////////////////////////////////////////////////// | |
502 | |
503 function context(phase, stage, mode, local) { | |
504 return {phase: phase, stage: stage, mode: mode, local: local}; | |
505 } | |
506 | |
507 function change(state, tok, ctx) { | |
508 state.tok = tok; | |
509 state.ctx = ctx || {}; | |
510 } | |
511 | |
512 function stage(state) { | |
513 return state.ctx.stage || 0; | |
514 } | |
515 | |
516 function phase(state) { | |
517 return state.ctx.phase; | |
518 } | |
519 | |
520 /////////////////////////////////////////////////////////////////////////// | |
521 /////////////////////////////////////////////////////////////////////////// | |
522 | |
523 return { | |
524 startState: function () { | |
525 return {tok: to_normal, ctx: context(undefined, 0)}; | |
526 }, | |
527 | |
528 copyState: function (state) { | |
529 var ctx = state.ctx, tmp = state.tmp; | |
530 if (ctx.local) | |
531 ctx = {mode: ctx.mode, local: CodeMirror.copyState(ctx.mode, ctx.local)}; | |
532 if (tmp) | |
533 tmp = {mode: tmp.mode, local: CodeMirror.copyState(tmp.mode, tmp.local)}; | |
534 return {tok: state.tok, ctx: ctx, tmp: tmp}; | |
535 }, | |
536 | |
537 innerMode: function (state) { | |
538 return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode} | |
539 : state.ctx.mode ? {state: state.ctx.local, mode: state.ctx.mode} | |
540 : null; | |
541 }, | |
542 | |
543 token: function (stream, state) { | |
544 return state.tok(stream, state); | |
545 } | |
546 }; | |
547 }, 'python', 'stex'); | |
548 | |
549 /////////////////////////////////////////////////////////////////////////////// | |
550 /////////////////////////////////////////////////////////////////////////////// | |
551 | |
552 CodeMirror.defineMIME('text/x-rst', 'rst'); | |
553 | |
554 /////////////////////////////////////////////////////////////////////////////// | |
555 /////////////////////////////////////////////////////////////////////////////// | |
556 | |
557 }); |