X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=third-party%2Fcodemirror-3.15%2Fmode%2Frst%2Frst.js;fp=third-party%2Fcodemirror-3.15%2Fmode%2Frst%2Frst.js;h=508896d25b3cd4fbd1e8ddb5539fbb90c6f5ed8c;hb=75d3bceb8e1d168e83982f910a916aee3bab7981;hp=0000000000000000000000000000000000000000;hpb=302dd5bda1297ed6579ca26da35ee67f8d35d934;p=unfold.git diff --git a/third-party/codemirror-3.15/mode/rst/rst.js b/third-party/codemirror-3.15/mode/rst/rst.js new file mode 100644 index 00000000..508896d2 --- /dev/null +++ b/third-party/codemirror-3.15/mode/rst/rst.js @@ -0,0 +1,561 @@ +CodeMirror.defineMode('rst-base', function (config) { + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function format(string) { + var args = Array.prototype.slice.call(arguments, 1); + return string.replace(/{(\d+)}/g, function (match, n) { + return typeof args[n] != 'undefined' ? args[n] : match; + }); + } + + function AssertException(message) { + this.message = message; + } + + AssertException.prototype.toString = function () { + return 'AssertException: ' + this.message; + }; + + function assert(expression, message) { + if (!expression) throw new AssertException(message); + return expression; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + var mode_python = CodeMirror.getMode(config, 'python'); + var mode_stex = CodeMirror.getMode(config, 'stex'); + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + var SEPA = "\\s+"; + var TAIL = "(?:\\s*|\\W|$)", + rx_TAIL = new RegExp(format('^{0}', TAIL)); + + var NAME = + "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)", + rx_NAME = new RegExp(format('^{0}', NAME)); + var NAME_WWS = + "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)"; + var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS); + + var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)"; + var TEXT2 = "(?:[^\\`]+)", + rx_TEXT2 = new RegExp(format('^{0}', TEXT2)); + + var rx_section = new RegExp( + "^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$"); + var rx_explicit = new RegExp( + format('^\\.\\.{0}', SEPA)); + var rx_link = new RegExp( + format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL)); + var rx_directive = new RegExp( + format('^{0}::{1}', REF_NAME, TAIL)); + var rx_substitution = new RegExp( + format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL)); + var rx_footnote = new RegExp( + format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL)); + var rx_citation = new RegExp( + format('^\\[{0}\\]{1}', REF_NAME, TAIL)); + + var rx_substitution_ref = new RegExp( + format('^\\|{0}\\|', TEXT1)); + var rx_footnote_ref = new RegExp( + format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME)); + var rx_citation_ref = new RegExp( + format('^\\[{0}\\]_', REF_NAME)); + var rx_link_ref1 = new RegExp( + format('^{0}__?', REF_NAME)); + var rx_link_ref2 = new RegExp( + format('^`{0}`_', TEXT2)); + + var rx_role_pre = new RegExp( + format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL)); + var rx_role_suf = new RegExp( + format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL)); + var rx_role = new RegExp( + format('^:{0}:{1}', NAME, TAIL)); + + var rx_directive_name = new RegExp(format('^{0}', REF_NAME)); + var rx_directive_tail = new RegExp(format('^::{0}', TAIL)); + var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1)); + var rx_substitution_sepa = new RegExp(format('^{0}', SEPA)); + var rx_substitution_name = new RegExp(format('^{0}', REF_NAME)); + var rx_substitution_tail = new RegExp(format('^::{0}', TAIL)); + var rx_link_head = new RegExp("^_"); + var rx_link_name = new RegExp(format('^{0}|_', REF_NAME)); + var rx_link_tail = new RegExp(format('^:{0}', TAIL)); + + var rx_verbatim = new RegExp('^::\\s*$'); + var rx_examples = new RegExp('^\\s+(?:>>>|In \\[\\d+\\]:)\\s'); + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_normal(stream, state) { + var token = null; + + if (stream.sol() && stream.match(rx_examples, false)) { + change(state, to_mode, { + mode: mode_python, local: mode_python.startState() + }); + } else if (stream.sol() && stream.match(rx_explicit)) { + change(state, to_explicit); + token = 'meta'; + } else if (stream.sol() && stream.match(rx_section)) { + change(state, to_normal); + token = 'header'; + } else if (phase(state) == rx_role_pre || + stream.match(rx_role_pre, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_role_pre, 1)); + assert(stream.match(/^:/)); + token = 'meta'; + break; + case 1: + change(state, to_normal, context(rx_role_pre, 2)); + assert(stream.match(rx_NAME)); + token = 'keyword'; + + if (stream.current().match(/^(?:math|latex)/)) { + state.tmp = { + mode: mode_stex, local: mode_stex.startState() + }; + } + break; + case 2: + change(state, to_normal, context(rx_role_pre, 3)); + assert(stream.match(/^:`/)); + token = 'meta'; + break; + case 3: + if (state.tmp) { + if (stream.peek() == '`') { + change(state, to_normal, context(rx_role_pre, 4)); + state.tmp = undefined; + break; + } + + token = state.tmp.mode.token(stream, state.tmp.local); + break; + } + + change(state, to_normal, context(rx_role_pre, 4)); + assert(stream.match(rx_TEXT2)); + token = 'string'; + break; + case 4: + change(state, to_normal, context(rx_role_pre, 5)); + assert(stream.match(/^`/)); + token = 'meta'; + break; + case 5: + change(state, to_normal, context(rx_role_pre, 6)); + assert(stream.match(rx_TAIL)); + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (phase(state) == rx_role_suf || + stream.match(rx_role_suf, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_role_suf, 1)); + assert(stream.match(/^`/)); + token = 'meta'; + break; + case 1: + change(state, to_normal, context(rx_role_suf, 2)); + assert(stream.match(rx_TEXT2)); + token = 'string'; + break; + case 2: + change(state, to_normal, context(rx_role_suf, 3)); + assert(stream.match(/^`:/)); + token = 'meta'; + break; + case 3: + change(state, to_normal, context(rx_role_suf, 4)); + assert(stream.match(rx_NAME)); + token = 'keyword'; + break; + case 4: + change(state, to_normal, context(rx_role_suf, 5)); + assert(stream.match(/^:/)); + token = 'meta'; + break; + case 5: + change(state, to_normal, context(rx_role_suf, 6)); + assert(stream.match(rx_TAIL)); + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (phase(state) == rx_role || stream.match(rx_role, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_role, 1)); + assert(stream.match(/^:/)); + token = 'meta'; + break; + case 1: + change(state, to_normal, context(rx_role, 2)); + assert(stream.match(rx_NAME)); + token = 'keyword'; + break; + case 2: + change(state, to_normal, context(rx_role, 3)); + assert(stream.match(/^:/)); + token = 'meta'; + break; + case 3: + change(state, to_normal, context(rx_role, 4)); + assert(stream.match(rx_TAIL)); + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (phase(state) == rx_substitution_ref || + stream.match(rx_substitution_ref, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_substitution_ref, 1)); + assert(stream.match(rx_substitution_text)); + token = 'variable-2'; + break; + case 1: + change(state, to_normal, context(rx_substitution_ref, 2)); + if (stream.match(/^_?_?/)) token = 'link'; + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (stream.match(rx_footnote_ref)) { + change(state, to_normal); + token = 'quote'; + } else if (stream.match(rx_citation_ref)) { + change(state, to_normal); + token = 'quote'; + } else if (stream.match(rx_link_ref1)) { + change(state, to_normal); + if (!stream.peek() || stream.peek().match(/^\W$/)) { + token = 'link'; + } + } else if (phase(state) == rx_link_ref2 || + stream.match(rx_link_ref2, false)) { + + switch (stage(state)) { + case 0: + if (!stream.peek() || stream.peek().match(/^\W$/)) { + change(state, to_normal, context(rx_link_ref2, 1)); + } else { + stream.match(rx_link_ref2); + } + break; + case 1: + change(state, to_normal, context(rx_link_ref2, 2)); + assert(stream.match(/^`/)); + token = 'link'; + break; + case 2: + change(state, to_normal, context(rx_link_ref2, 3)); + assert(stream.match(rx_TEXT2)); + break; + case 3: + change(state, to_normal, context(rx_link_ref2, 4)); + assert(stream.match(/^`_/)); + token = 'link'; + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (stream.match(rx_verbatim)) { + change(state, to_verbatim); + } + + else { + if (stream.next()) change(state, to_normal); + } + + return token; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_explicit(stream, state) { + var token = null; + + if (phase(state) == rx_substitution || + stream.match(rx_substitution, false)) { + + switch (stage(state)) { + case 0: + change(state, to_explicit, context(rx_substitution, 1)); + assert(stream.match(rx_substitution_text)); + token = 'variable-2'; + break; + case 1: + change(state, to_explicit, context(rx_substitution, 2)); + assert(stream.match(rx_substitution_sepa)); + break; + case 2: + change(state, to_explicit, context(rx_substitution, 3)); + assert(stream.match(rx_substitution_name)); + token = 'keyword'; + break; + case 3: + change(state, to_explicit, context(rx_substitution, 4)); + assert(stream.match(rx_substitution_tail)); + token = 'meta'; + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (phase(state) == rx_directive || + stream.match(rx_directive, false)) { + + switch (stage(state)) { + case 0: + change(state, to_explicit, context(rx_directive, 1)); + assert(stream.match(rx_directive_name)); + token = 'keyword'; + + if (stream.current().match(/^(?:math|latex)/)) + state.tmp_stex = true; + else if (stream.current().match(/^python/)) + state.tmp_py = true; + break; + case 1: + change(state, to_explicit, context(rx_directive, 2)); + assert(stream.match(rx_directive_tail)); + token = 'meta'; + break; + default: + if (stream.match(/^latex\s*$/) || state.tmp_stex) { + state.tmp_stex = undefined; + change(state, to_mode, { + mode: mode_stex, local: mode_stex.startState() + }); + } else if (stream.match(/^python\s*$/) || state.tmp_py) { + state.tmp_py = undefined; + change(state, to_mode, { + mode: mode_python, local: mode_python.startState() + }); + } + + else { + change(state, to_normal); + assert(stream.current() == ''); + } + } + } else if (phase(state) == rx_link || stream.match(rx_link, false)) { + + switch (stage(state)) { + case 0: + change(state, to_explicit, context(rx_link, 1)); + assert(stream.match(rx_link_head)); + assert(stream.match(rx_link_name)); + token = 'link'; + break; + case 1: + change(state, to_explicit, context(rx_link, 2)); + assert(stream.match(rx_link_tail)); + token = 'meta'; + break; + default: + change(state, to_normal); + assert(stream.current() == ''); + } + } else if (stream.match(rx_footnote)) { + change(state, to_normal); + token = 'quote'; + } else if (stream.match(rx_citation)) { + change(state, to_normal); + token = 'quote'; + } + + else { + stream.eatSpace(); + if (stream.eol()) { + change(state, to_normal); + } else { + stream.skipToEnd(); + change(state, to_comment); + token = 'comment'; + } + } + + return token; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_comment(stream, state) { + return as_block(stream, state, 'comment'); + } + + function to_verbatim(stream, state) { + return as_block(stream, state, 'meta'); + } + + function as_block(stream, state, token) { + if (stream.eol() || stream.eatSpace()) { + stream.skipToEnd(); + return token; + } else { + change(state, to_normal); + return null; + } + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_mode(stream, state) { + + if (state.ctx.mode && state.ctx.local) { + + if (stream.sol()) { + if (!stream.eatSpace()) change(state, to_normal); + return null; + } + + try { + return state.ctx.mode.token(stream, state.ctx.local); + } catch (ex) { + change(state, to_normal); + return null; + } + } + + change(state, to_normal); + return null; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function context(phase, stage, mode, local) { + return {phase: phase, stage: stage, mode: mode, local: local}; + } + + function change(state, tok, ctx) { + state.tok = tok; + state.ctx = ctx || {}; + } + + function stage(state) { + return state.ctx.stage || 0; + } + + function phase(state) { + return state.ctx.phase; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + return { + startState: function () { + return {tok: to_normal, ctx: context(undefined, 0)}; + }, + + copyState: function (state) { + return {tok: state.tok, ctx: state.ctx}; + }, + + innerMode: function (state) { + return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode} + : state.ctx ? {state: state.ctx.local, mode: state.ctx.mode} + : null; + }, + + token: function (stream, state) { + return state.tok(stream, state); + } + }; +}, 'python', 'stex'); + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +CodeMirror.defineMode('rst', function (config, options) { + + var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/; + var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/; + var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/; + + var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/; + var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/; + var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/; + + var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://"; + var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})"; + var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*"; + var rx_uri = new RegExp("^" + + rx_uri_protocol + rx_uri_domain + rx_uri_path + ); + + var overlay = { + token: function (stream) { + + if (stream.match(rx_strong) && stream.match (/\W+|$/, false)) + return 'strong'; + if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false)) + return 'em'; + if (stream.match(rx_literal) && stream.match (/\W+|$/, false)) + return 'string-2'; + if (stream.match(rx_number)) + return 'number'; + if (stream.match(rx_positive)) + return 'positive'; + if (stream.match(rx_negative)) + return 'negative'; + if (stream.match(rx_uri)) + return 'link'; + + while (stream.next() != null) { + if (stream.match(rx_strong, false)) break; + if (stream.match(rx_emphasis, false)) break; + if (stream.match(rx_literal, false)) break; + if (stream.match(rx_number, false)) break; + if (stream.match(rx_positive, false)) break; + if (stream.match(rx_negative, false)) break; + if (stream.match(rx_uri, false)) break; + } + + return null; + } + }; + + var mode = CodeMirror.getMode( + config, options.backdrop || 'rst-base' + ); + + return CodeMirror.overlayMode(mode, overlay, true); // combine +}, 'python', 'stex'); + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +CodeMirror.defineMIME('text/x-rst', 'rst'); + +/////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////