1
CodeMirror.defineMode('rst', function(config, options) {
2
function setState(state, fn, ctx) {
7
function setCtx(state, ctx) {
11
function setNormal(state, ch) {
12
if (ch && (typeof ch !== 'string')) {
13
var str = ch.current();
14
ch = str[str.length-1];
17
setState(state, normal, {back: ch});
20
function hasMode(mode) {
22
var modes = CodeMirror.listModes();
24
for (var i in modes) {
25
if (modes[i] == mode) {
34
function getMode(mode) {
36
return CodeMirror.getMode(config, mode);
42
var verbatimMode = getMode(options.verbatim);
43
var pythonMode = getMode('python');
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/;
60
function normal(stream, state) {
63
if (stream.eat(/\\/)) {
71
if (sol && (ch = stream.eat(reSection))) {
72
for (i = 0; stream.eat(ch); i++);
74
if (i >= 3 && stream.match(/^\s*$/)) {
75
setNormal(state, null);
82
if (sol && stream.match(reDirectiveMarker)) {
84
setState(state, directive);
89
if (stream.match(reVerbatimMarker)) {
91
setState(state, verbatim);
93
var mode = verbatimMode;
95
setState(state, verbatim, {
97
local: mode.startState()
103
if (sol && stream.match(reExamples, false)) {
105
setState(state, verbatim);
108
var mode = pythonMode;
110
setState(state, verbatim, {
112
local: mode.startState()
119
function testBackward(re) {
120
return sol || !state.ctx.back || re.test(state.ctx.back);
123
function testForward(re) {
124
return stream.eol() || stream.match(re, false);
127
function testInline(re) {
128
return stream.match(re) && testBackward(/\W/) && testForward(/\W/);
131
if (testInline(reFootnoteRef)) {
132
setNormal(state, stream);
136
if (testInline(reCitationRef)) {
137
setNormal(state, stream);
143
if (testBackward(rePreInline)) {
144
if ((ch === ':' || ch === '|') && stream.eat(/\S/)) {
153
setState(state, inline, {
163
if (ch === '*' || ch === '`') {
174
if (ch && !/\s/.test(ch)) {
178
token = wide ? 'strong' : 'em';
180
token = wide ? 'string' : 'string-2';
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
195
setNormal(state, ch);
199
function inline(stream, state) {
200
var ch = stream.next(),
201
token = state.ctx.token;
203
function finish(ch) {
208
if (ch != state.ctx.ch) {
212
if (/\s/.test(state.ctx.prev)) {
216
if (state.ctx.wide) {
219
if (ch != state.ctx.ch) {
224
if (!stream.eol() && !rePostInline.test(stream.peek())) {
225
if (state.ctx.wide) {
232
setState(state, normal);
233
setNormal(state, ch);
238
function directive(stream, state) {
241
if (stream.match(reDirective)) {
243
} else if (stream.match(reHyperlink)) {
245
} else if (stream.match(reFootnote)) {
247
} else if (stream.match(reCitation)) {
253
setNormal(state, stream);
257
setState(state, comment);
262
// FIXME this is unreachable
263
setState(state, body, {start: true});
267
function body(stream, state) {
270
if (!state.ctx.start || stream.sol()) {
271
return block(stream, state, token);
280
function comment(stream, state) {
281
return block(stream, state, 'comment');
284
function verbatim(stream, state) {
286
return block(stream, state, 'meta');
289
if (!stream.eatSpace()) {
290
setNormal(state, stream);
296
return verbatimMode.token(stream, state.ctx.local);
300
function block(stream, state, token) {
301
if (stream.eol() || stream.eatSpace()) {
305
setNormal(state, stream);
311
startState: function() {
312
return {fn: normal, ctx: {}};
315
copyState: function(state) {
316
return {fn: state.fn, ctx: state.ctx};
319
token: function(stream, state) {
320
var token = state.fn(stream, state);
326
CodeMirror.defineMIME("text/x-rst", "rst");