first commit
This commit is contained in:
314
codemirror/mode/rst/rst.js
vendored
Normal file
314
codemirror/mode/rst/rst.js
vendored
Normal file
@@ -0,0 +1,314 @@
|
||||
CodeMirror.defineMode('rst', function(config, options) {
|
||||
function setState(state, fn, ctx) {
|
||||
state.fn = fn;
|
||||
setCtx(state, ctx);
|
||||
}
|
||||
|
||||
function setCtx(state, ctx) {
|
||||
state.ctx = ctx || {};
|
||||
}
|
||||
|
||||
function setNormal(state, ch) {
|
||||
if (ch && (typeof ch !== 'string')) {
|
||||
var str = ch.current();
|
||||
ch = str[str.length-1];
|
||||
}
|
||||
|
||||
setState(state, normal, {back: ch});
|
||||
}
|
||||
|
||||
function hasMode(mode) {
|
||||
return mode && CodeMirror.modes.hasOwnProperty(mode);
|
||||
}
|
||||
|
||||
function getMode(mode) {
|
||||
if (hasMode(mode)) {
|
||||
return CodeMirror.getMode(config, mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var verbatimMode = getMode(options.verbatim);
|
||||
var pythonMode = getMode('python');
|
||||
|
||||
var reSection = /^[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/;
|
||||
var reDirective = /^\s*\w([-:.\w]*\w)?::(\s|$)/;
|
||||
var reHyperlink = /^\s*_[\w-]+:(\s|$)/;
|
||||
var reFootnote = /^\s*\[(\d+|#)\](\s|$)/;
|
||||
var reCitation = /^\s*\[[A-Za-z][\w-]*\](\s|$)/;
|
||||
var reFootnoteRef = /^\[(\d+|#)\]_/;
|
||||
var reCitationRef = /^\[[A-Za-z][\w-]*\]_/;
|
||||
var reDirectiveMarker = /^\.\.(\s|$)/;
|
||||
var reVerbatimMarker = /^::\s*$/;
|
||||
var rePreInline = /^[-\s"([{</:]/;
|
||||
var rePostInline = /^[-\s`'")\]}>/:.,;!?\\_]/;
|
||||
var reExamples = /^\s+(>>>|In \[\d+\]:)\s/;
|
||||
|
||||
function normal(stream, state) {
|
||||
var ch, sol, i;
|
||||
|
||||
if (stream.eat(/\\/)) {
|
||||
ch = stream.next();
|
||||
setNormal(state, ch);
|
||||
return null;
|
||||
}
|
||||
|
||||
sol = stream.sol();
|
||||
|
||||
if (sol && (ch = stream.eat(reSection))) {
|
||||
for (i = 0; stream.eat(ch); i++);
|
||||
|
||||
if (i >= 3 && stream.match(/^\s*$/)) {
|
||||
setNormal(state, null);
|
||||
return 'header';
|
||||
} else {
|
||||
stream.backUp(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (sol && stream.match(reDirectiveMarker)) {
|
||||
if (!stream.eol()) {
|
||||
setState(state, directive);
|
||||
}
|
||||
return 'meta';
|
||||
}
|
||||
|
||||
if (stream.match(reVerbatimMarker)) {
|
||||
if (!verbatimMode) {
|
||||
setState(state, verbatim);
|
||||
} else {
|
||||
var mode = verbatimMode;
|
||||
|
||||
setState(state, verbatim, {
|
||||
mode: mode,
|
||||
local: mode.startState()
|
||||
});
|
||||
}
|
||||
return 'meta';
|
||||
}
|
||||
|
||||
if (sol && stream.match(reExamples, false)) {
|
||||
if (!pythonMode) {
|
||||
setState(state, verbatim);
|
||||
return 'meta';
|
||||
} else {
|
||||
var mode = pythonMode;
|
||||
|
||||
setState(state, verbatim, {
|
||||
mode: mode,
|
||||
local: mode.startState()
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function testBackward(re) {
|
||||
return sol || !state.ctx.back || re.test(state.ctx.back);
|
||||
}
|
||||
|
||||
function testForward(re) {
|
||||
return stream.eol() || stream.match(re, false);
|
||||
}
|
||||
|
||||
function testInline(re) {
|
||||
return stream.match(re) && testBackward(/\W/) && testForward(/\W/);
|
||||
}
|
||||
|
||||
if (testInline(reFootnoteRef)) {
|
||||
setNormal(state, stream);
|
||||
return 'footnote';
|
||||
}
|
||||
|
||||
if (testInline(reCitationRef)) {
|
||||
setNormal(state, stream);
|
||||
return 'citation';
|
||||
}
|
||||
|
||||
ch = stream.next();
|
||||
|
||||
if (testBackward(rePreInline)) {
|
||||
if ((ch === ':' || ch === '|') && stream.eat(/\S/)) {
|
||||
var token;
|
||||
|
||||
if (ch === ':') {
|
||||
token = 'builtin';
|
||||
} else {
|
||||
token = 'atom';
|
||||
}
|
||||
|
||||
setState(state, inline, {
|
||||
ch: ch,
|
||||
wide: false,
|
||||
prev: null,
|
||||
token: token
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
if (ch === '*' || ch === '`') {
|
||||
var orig = ch,
|
||||
wide = false;
|
||||
|
||||
ch = stream.next();
|
||||
|
||||
if (ch == orig) {
|
||||
wide = true;
|
||||
ch = stream.next();
|
||||
}
|
||||
|
||||
if (ch && !/\s/.test(ch)) {
|
||||
var token;
|
||||
|
||||
if (orig === '*') {
|
||||
token = wide ? 'strong' : 'em';
|
||||
} else {
|
||||
token = wide ? 'string' : 'string-2';
|
||||
}
|
||||
|
||||
setState(state, inline, {
|
||||
ch: orig, // inline() has to know what to search for
|
||||
wide: wide, // are we looking for `ch` or `chch`
|
||||
prev: null, // terminator must not be preceeded with whitespace
|
||||
token: token // I don't want to recompute this all the time
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setNormal(state, ch);
|
||||
return null;
|
||||
}
|
||||
|
||||
function inline(stream, state) {
|
||||
var ch = stream.next(),
|
||||
token = state.ctx.token;
|
||||
|
||||
function finish(ch) {
|
||||
state.ctx.prev = ch;
|
||||
return token;
|
||||
}
|
||||
|
||||
if (ch != state.ctx.ch) {
|
||||
return finish(ch);
|
||||
}
|
||||
|
||||
if (/\s/.test(state.ctx.prev)) {
|
||||
return finish(ch);
|
||||
}
|
||||
|
||||
if (state.ctx.wide) {
|
||||
ch = stream.next();
|
||||
|
||||
if (ch != state.ctx.ch) {
|
||||
return finish(ch);
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream.eol() && !rePostInline.test(stream.peek())) {
|
||||
if (state.ctx.wide) {
|
||||
stream.backUp(1);
|
||||
}
|
||||
|
||||
return finish(ch);
|
||||
}
|
||||
|
||||
setState(state, normal);
|
||||
setNormal(state, ch);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
function directive(stream, state) {
|
||||
var token = null;
|
||||
|
||||
if (stream.match(reDirective)) {
|
||||
token = 'attribute';
|
||||
} else if (stream.match(reHyperlink)) {
|
||||
token = 'link';
|
||||
} else if (stream.match(reFootnote)) {
|
||||
token = 'quote';
|
||||
} else if (stream.match(reCitation)) {
|
||||
token = 'quote';
|
||||
} else {
|
||||
stream.eatSpace();
|
||||
|
||||
if (stream.eol()) {
|
||||
setNormal(state, stream);
|
||||
return null;
|
||||
} else {
|
||||
stream.skipToEnd();
|
||||
setState(state, comment);
|
||||
return 'comment';
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME this is unreachable
|
||||
setState(state, body, {start: true});
|
||||
return token;
|
||||
}
|
||||
|
||||
function body(stream, state) {
|
||||
var token = 'body';
|
||||
|
||||
if (!state.ctx.start || stream.sol()) {
|
||||
return block(stream, state, token);
|
||||
}
|
||||
|
||||
stream.skipToEnd();
|
||||
setCtx(state);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
function comment(stream, state) {
|
||||
return block(stream, state, 'comment');
|
||||
}
|
||||
|
||||
function verbatim(stream, state) {
|
||||
if (!verbatimMode) {
|
||||
return block(stream, state, 'meta');
|
||||
} else {
|
||||
if (stream.sol()) {
|
||||
if (!stream.eatSpace()) {
|
||||
setNormal(state, stream);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return verbatimMode.token(stream, state.ctx.local);
|
||||
}
|
||||
}
|
||||
|
||||
function block(stream, state, token) {
|
||||
if (stream.eol() || stream.eatSpace()) {
|
||||
stream.skipToEnd();
|
||||
return token;
|
||||
} else {
|
||||
setNormal(state, stream);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {fn: normal, ctx: {}};
|
||||
},
|
||||
|
||||
copyState: function(state) {
|
||||
return {fn: state.fn, ctx: state.ctx};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var token = state.fn(stream, state);
|
||||
return token;
|
||||
}
|
||||
};
|
||||
}, "python");
|
||||
|
||||
CodeMirror.defineMIME("text/x-rst", "rst");
|
||||
Reference in New Issue
Block a user