aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/rst/rst.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/rst/rst.js')
-rwxr-xr-ximports/codemirror/mode/rst/rst.js326
1 files changed, 326 insertions, 0 deletions
diff --git a/imports/codemirror/mode/rst/rst.js b/imports/codemirror/mode/rst/rst.js
new file mode 100755
index 00000000..411bac56
--- /dev/null
+++ b/imports/codemirror/mode/rst/rst.js
@@ -0,0 +1,326 @@
1CodeMirror.defineMode('rst', function(config, options) {
2 function setState(state, fn, ctx) {
3 state.fn = fn;
4 setCtx(state, ctx);
5 }
6
7 function setCtx(state, ctx) {
8 state.ctx = ctx || {};
9 }
10
11 function setNormal(state, ch) {
12 if (ch && (typeof ch !== 'string')) {
13 var str = ch.current();
14 ch = str[str.length-1];
15 }
16
17 setState(state, normal, {back: ch});
18 }
19
20 function hasMode(mode) {
21 if (mode) {
22 var modes = CodeMirror.listModes();
23
24 for (var i in modes) {
25 if (modes[i] == mode) {
26 return true;
27 }
28 }
29 }
30
31 return false;
32 }
33
34 function getMode(mode) {
35 if (hasMode(mode)) {
36 return CodeMirror.getMode(config, mode);
37 } else {
38 return null;
39 }
40 }
41
42 var verbatimMode = getMode(options.verbatim);
43 var pythonMode = getMode('python');
44
45 var reSection = /^[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/;
46 var reDirective = /^\s*\w([-:.\w]*\w)?::(\s|$)/;
47 var reHyperlink = /^\s*_[\w-]+:(\s|$)/;
48 var reFootnote = /^\s*\[(\d+|#)\](\s|$)/;
49 var reCitation = /^\s*\[[A-Za-z][\w-]*\](\s|$)/;
50 var reFootnoteRef = /^\[(\d+|#)\]_/;
51 var reCitationRef = /^\[[A-Za-z][\w-]*\]_/;
52 var reDirectiveMarker = /^\.\.(\s|$)/;
53 var reVerbatimMarker = /^::\s*$/;
54 var rePreInline = /^[-\s"([{</:]/;
55 var rePostInline = /^[-\s`'")\]}>/:.,;!?\\_]/;
56 var reEnumeratedList = /^\s*((\d+|[A-Za-z#])[.)]|\((\d+|[A-Z-a-z#])\))\s/;
57 var reBulletedList = /^\s*[-\+\*]\s/;
58 var reExamples = /^\s+(>>>|In \[\d+\]:)\s/;
59
60 function normal(stream, state) {
61 var ch, sol, i;
62
63 if (stream.eat(/\\/)) {
64 ch = stream.next();
65 setNormal(state, ch);
66 return null;
67 }
68
69 sol = stream.sol();
70
71 if (sol && (ch = stream.eat(reSection))) {
72 for (i = 0; stream.eat(ch); i++);
73
74 if (i >= 3 && stream.match(/^\s*$/)) {
75 setNormal(state, null);
76 return 'header';
77 } else {
78 stream.backUp(i + 1);
79 }
80 }
81
82 if (sol && stream.match(reDirectiveMarker)) {
83 if (!stream.eol()) {
84 setState(state, directive);
85 }
86 return 'meta';
87 }
88
89 if (stream.match(reVerbatimMarker)) {
90 if (!verbatimMode) {
91 setState(state, verbatim);
92 } else {
93 var mode = verbatimMode;
94
95 setState(state, verbatim, {
96 mode: mode,
97 local: mode.startState()
98 });
99 }
100 return 'meta';
101 }
102
103 if (sol && stream.match(reExamples, false)) {
104 if (!pythonMode) {
105 setState(state, verbatim);
106 return 'meta';
107 } else {
108 var mode = pythonMode;
109
110 setState(state, verbatim, {
111 mode: mode,
112 local: mode.startState()
113 });
114
115 return null;
116 }
117 }
118
119 function testBackward(re) {
120 return sol || !state.ctx.back || re.test(state.ctx.back);
121 }
122
123 function testForward(re) {
124 return stream.eol() || stream.match(re, false);
125 }
126
127 function testInline(re) {
128 return stream.match(re) && testBackward(/\W/) && testForward(/\W/);
129 }
130
131 if (testInline(reFootnoteRef)) {
132 setNormal(state, stream);
133 return 'footnote';
134 }
135
136 if (testInline(reCitationRef)) {
137 setNormal(state, stream);
138 return 'citation';
139 }
140
141 ch = stream.next();
142
143 if (testBackward(rePreInline)) {
144 if ((ch === ':' || ch === '|') && stream.eat(/\S/)) {
145 var token;
146
147 if (ch === ':') {
148 token = 'builtin';
149 } else {
150 token = 'atom';
151 }
152
153 setState(state, inline, {
154 ch: ch,
155 wide: false,
156 prev: null,
157 token: token
158 });
159
160 return token;
161 }
162
163 if (ch === '*' || ch === '`') {
164 var orig = ch,
165 wide = false;
166
167 ch = stream.next();
168
169 if (ch == orig) {
170 wide = true;
171 ch = stream.next();
172 }
173
174 if (ch && !/\s/.test(ch)) {
175 var token;
176
177 if (orig === '*') {
178 token = wide ? 'strong' : 'em';
179 } else {
180 token = wide ? 'string' : 'string-2';
181 }
182
183 setState(state, inline, {
184 ch: orig, // inline() has to know what to search for
185 wide: wide, // are we looking for `ch` or `chch`
186 prev: null, // terminator must not be preceeded with whitespace
187 token: token // I don't want to recompute this all the time
188 });
189
190 return token;
191 }
192 }
193 }
194
195 setNormal(state, ch);
196 return null;
197 }
198
199 function inline(stream, state) {
200 var ch = stream.next(),
201 token = state.ctx.token;
202
203 function finish(ch) {
204 state.ctx.prev = ch;
205 return token;
206 }
207
208 if (ch != state.ctx.ch) {
209 return finish(ch);
210 }
211
212 if (/\s/.test(state.ctx.prev)) {
213 return finish(ch);
214 }
215
216 if (state.ctx.wide) {
217 ch = stream.next();
218
219 if (ch != state.ctx.ch) {
220 return finish(ch);
221 }
222 }
223
224 if (!stream.eol() && !rePostInline.test(stream.peek())) {
225 if (state.ctx.wide) {
226 stream.backUp(1);
227 }
228
229 return finish(ch);
230 }
231
232 setState(state, normal);
233 setNormal(state, ch);
234
235 return token;
236 }
237
238 function directive(stream, state) {
239 var token = null;
240
241 if (stream.match(reDirective)) {
242 token = 'attribute';