diff options
author | Armen Kesablyan | 2012-02-22 16:26:41 -0800 |
---|---|---|
committer | Armen Kesablyan | 2012-02-22 16:26:41 -0800 |
commit | 0bd1cefea2ab350fad1a891bdc926053b799aafc (patch) | |
tree | 962f559fcc02a3dfeb297d59907e40fa153453f3 /imports/codemirror/mode/rst/rst.js | |
parent | 695bc5082f48dddf66ce31480a4faefc067b38bd (diff) | |
parent | 2d2b1af8b5c0d506fe6a1cf65614101fec145970 (diff) | |
download | ninja-0bd1cefea2ab350fad1a891bdc926053b799aafc.tar.gz |
Merge branch 'refs/heads/master' into new-tool-icons
Diffstat (limited to 'imports/codemirror/mode/rst/rst.js')
-rwxr-xr-x | imports/codemirror/mode/rst/rst.js | 326 |
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 @@ | |||
1 | CodeMirror.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; | ||