Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/codemirror/mode/rst.js
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45// CodeMirror, copyright (c) by Marijn Haverbeke and others6// Distributed under an MIT license: http://codemirror.net/LICENSE78"use strict";910import * as CodeMirror from "codemirror";1112CodeMirror.defineMode('rst', function (config, options) {1314var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;15var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/;16var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/;1718var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;19var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;20var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;2122var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";23var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";24var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";25var rx_uri = new RegExp("^" + rx_uri_protocol + rx_uri_domain + rx_uri_path);2627var overlay = {28token: function (stream) {2930if (stream.match(rx_strong) && stream.match (/\W+|$/, false))31return 'strong';32if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false))33return 'em';34if (stream.match(rx_literal) && stream.match (/\W+|$/, false))35return 'string-2';36if (stream.match(rx_number))37return 'number';38if (stream.match(rx_positive))39return 'positive';40if (stream.match(rx_negative))41return 'negative';42if (stream.match(rx_uri))43return 'link';4445while (stream.next() != null) {46if (stream.match(rx_strong, false)) break;47if (stream.match(rx_emphasis, false)) break;48if (stream.match(rx_literal, false)) break;49if (stream.match(rx_number, false)) break;50if (stream.match(rx_positive, false)) break;51if (stream.match(rx_negative, false)) break;52if (stream.match(rx_uri, false)) break;53}5455return null;56}57};5859var mode = CodeMirror.getMode(60config, options.backdrop || 'rst-base'61);6263return CodeMirror.overlayMode(mode, overlay, true); // combine64}, 'python', 'stex');6566///////////////////////////////////////////////////////////////////////////////67///////////////////////////////////////////////////////////////////////////////6869CodeMirror.defineMode('rst-base', function (config) {7071///////////////////////////////////////////////////////////////////////////72///////////////////////////////////////////////////////////////////////////7374function format(string) {75var args = Array.prototype.slice.call(arguments, 1);76return string.replace(/{(\d+)}/g, function (match, n) {77return typeof args[n] != 'undefined' ? args[n] : match;78});79}8081///////////////////////////////////////////////////////////////////////////82///////////////////////////////////////////////////////////////////////////8384var mode_python = CodeMirror.getMode(config, 'python');85var mode_stex = CodeMirror.getMode(config, 'stex');8687///////////////////////////////////////////////////////////////////////////88///////////////////////////////////////////////////////////////////////////8990var SEPA = "\\s+";91var TAIL = "(?:\\s*|\\W|$)",92rx_TAIL = new RegExp(format('^{0}', TAIL));9394var NAME =95"(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)",96rx_NAME = new RegExp(format('^{0}', NAME));97var NAME_WWS =98"(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)";99var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);100101var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";102var TEXT2 = "(?:[^\\`]+)",103rx_TEXT2 = new RegExp(format('^{0}', TEXT2));104105var rx_section = new RegExp(106"^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$");107var rx_explicit = new RegExp(108format('^\\.\\.{0}', SEPA));109var rx_link = new RegExp(110format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL));111var rx_directive = new RegExp(112format('^{0}::{1}', REF_NAME, TAIL));113var rx_substitution = new RegExp(114format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL));115var rx_footnote = new RegExp(116format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL));117var rx_citation = new RegExp(118format('^\\[{0}\\]{1}', REF_NAME, TAIL));119120var rx_substitution_ref = new RegExp(121format('^\\|{0}\\|', TEXT1));122var rx_footnote_ref = new RegExp(123format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME));124var rx_citation_ref = new RegExp(125format('^\\[{0}\\]_', REF_NAME));126var rx_link_ref1 = new RegExp(127format('^{0}__?', REF_NAME));128var rx_link_ref2 = new RegExp(129format('^`{0}`_', TEXT2));130131var rx_role_pre = new RegExp(132format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL));133var rx_role_suf = new RegExp(134format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL));135var rx_role = new RegExp(136format('^:{0}:{1}', NAME, TAIL));137138var rx_directive_name = new RegExp(format('^{0}', REF_NAME));139var rx_directive_tail = new RegExp(format('^::{0}', TAIL));140var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1));141var rx_substitution_sepa = new RegExp(format('^{0}', SEPA));142var rx_substitution_name = new RegExp(format('^{0}', REF_NAME));143var rx_substitution_tail = new RegExp(format('^::{0}', TAIL));144var rx_link_head = new RegExp("^_");145var rx_link_name = new RegExp(format('^{0}|_', REF_NAME));146var rx_link_tail = new RegExp(format('^:{0}', TAIL));147148var rx_verbatim = new RegExp('^::\\s*$');149var rx_examples = new RegExp('^\\s+(?:>>>|sage:|In \\[\\d+\\]:)\\s');150151///////////////////////////////////////////////////////////////////////////152///////////////////////////////////////////////////////////////////////////153154function to_normal(stream, state) {155var token = null;156157if (stream.sol() && stream.match(rx_examples, false)) {158change(state, to_mode, {159mode: mode_python, local: CodeMirror.startState(mode_python)160});161} else if (stream.sol() && stream.match(rx_explicit)) {162change(state, to_explicit);163token = 'meta';164} else if (stream.sol() && stream.match(rx_section)) {165change(state, to_normal);166token = 'header';167} else if (phase(state) == rx_role_pre ||168stream.match(rx_role_pre, false)) {169170switch (stage(state)) {171case 0:172change(state, to_normal, context(rx_role_pre, 1));173stream.match(/^:/);174token = 'meta';175break;176case 1:177change(state, to_normal, context(rx_role_pre, 2));178stream.match(rx_NAME);179token = 'keyword';180181if (stream.current().match(/^(?:math|latex)/)) {182state.tmp_stex = true;183}184break;185case 2:186change(state, to_normal, context(rx_role_pre, 3));187stream.match(/^:`/);188token = 'meta';189break;190case 3:191if (state.tmp_stex) {192state.tmp_stex = undefined; state.tmp = {193mode: mode_stex, local: CodeMirror.startState(mode_stex)194};195}196197if (state.tmp) {198if (stream.peek() == '`') {199change(state, to_normal, context(rx_role_pre, 4));200state.tmp = undefined;201break;202}203204token = state.tmp.mode.token(stream, state.tmp.local);205break;206}207208change(state, to_normal, context(rx_role_pre, 4));209stream.match(rx_TEXT2);210token = 'string';211break;212case 4:213change(state, to_normal, context(rx_role_pre, 5));214stream.match(/^`/);215token = 'meta';216break;217case 5:218change(state, to_normal, context(rx_role_pre, 6));219stream.match(rx_TAIL);220break;221default:222change(state, to_normal);223}224} else if (phase(state) == rx_role_suf ||225stream.match(rx_role_suf, false)) {226227switch (stage(state)) {228case 0:229change(state, to_normal, context(rx_role_suf, 1));230stream.match(/^`/);231token = 'meta';232break;233case 1:234change(state, to_normal, context(rx_role_suf, 2));235stream.match(rx_TEXT2);236token = 'string';237break;238case 2:239change(state, to_normal, context(rx_role_suf, 3));240stream.match(/^`:/);241token = 'meta';242break;243case 3:244change(state, to_normal, context(rx_role_suf, 4));245stream.match(rx_NAME);246token = 'keyword';247break;248case 4:249change(state, to_normal, context(rx_role_suf, 5));250stream.match(/^:/);251token = 'meta';252break;253case 5:254change(state, to_normal, context(rx_role_suf, 6));255stream.match(rx_TAIL);256break;257default:258change(state, to_normal);259}260} else if (phase(state) == rx_role || stream.match(rx_role, false)) {261262switch (stage(state)) {263case 0:264change(state, to_normal, context(rx_role, 1));265stream.match(/^:/);266token = 'meta';267break;268case 1:269change(state, to_normal, context(rx_role, 2));270stream.match(rx_NAME);271token = 'keyword';272break;273case 2:274change(state, to_normal, context(rx_role, 3));275stream.match(/^:/);276token = 'meta';277break;278case 3:279change(state, to_normal, context(rx_role, 4));280stream.match(rx_TAIL);281break;282default:283change(state, to_normal);284}285} else if (phase(state) == rx_substitution_ref ||286stream.match(rx_substitution_ref, false)) {287288switch (stage(state)) {289case 0:290change(state, to_normal, context(rx_substitution_ref, 1));291stream.match(rx_substitution_text);292token = 'variable-2';293break;294case 1:295change(state, to_normal, context(rx_substitution_ref, 2));296if (stream.match(/^_?_?/)) token = 'link';297break;298default:299change(state, to_normal);300}301} else if (stream.match(rx_footnote_ref)) {302change(state, to_normal);303token = 'quote';304} else if (stream.match(rx_citation_ref)) {305change(state, to_normal);306token = 'quote';307} else if (stream.match(rx_link_ref1)) {308change(state, to_normal);309if (!stream.peek() || stream.peek().match(/^\W$/)) {310token = 'link';311}312} else if (phase(state) == rx_link_ref2 ||313stream.match(rx_link_ref2, false)) {314315switch (stage(state)) {316case 0:317if (!stream.peek() || stream.peek().match(/^\W$/)) {318change(state, to_normal, context(rx_link_ref2, 1));319} else {320stream.match(rx_link_ref2);321}322break;323case 1:324change(state, to_normal, context(rx_link_ref2, 2));325stream.match(/^`/);326token = 'link';327break;328case 2:329change(state, to_normal, context(rx_link_ref2, 3));330stream.match(rx_TEXT2);331break;332case 3:333change(state, to_normal, context(rx_link_ref2, 4));334stream.match(/^`_/);335token = 'link';336break;337default:338change(state, to_normal);339}340} else if (stream.match(rx_verbatim)) {341change(state, to_verbatim);342}343344else {345if (stream.next()) change(state, to_normal);346}347348return token;349}350351///////////////////////////////////////////////////////////////////////////352///////////////////////////////////////////////////////////////////////////353354function to_explicit(stream, state) {355var token = null;356357if (phase(state) == rx_substitution ||358stream.match(rx_substitution, false)) {359360switch (stage(state)) {361case 0:362change(state, to_explicit, context(rx_substitution, 1));363stream.match(rx_substitution_text);364token = 'variable-2';365break;366case 1:367change(state, to_explicit, context(rx_substitution, 2));368stream.match(rx_substitution_sepa);369break;370case 2:371change(state, to_explicit, context(rx_substitution, 3));372stream.match(rx_substitution_name);373token = 'keyword';374break;375case 3:376change(state, to_explicit, context(rx_substitution, 4));377stream.match(rx_substitution_tail);378token = 'meta';379break;380default:381change(state, to_normal);382}383} else if (phase(state) == rx_directive ||384stream.match(rx_directive, false)) {385386switch (stage(state)) {387case 0:388change(state, to_explicit, context(rx_directive, 1));389stream.match(rx_directive_name);390token = 'keyword';391392if (stream.current().match(/^(?:math|latex)/))393state.tmp_stex = true;394else if (stream.current().match(/^python/))395state.tmp_py = true;396break;397case 1:398change(state, to_explicit, context(rx_directive, 2));399stream.match(rx_directive_tail);400token = 'meta';401402if (stream.match(/^latex\s*$/) || state.tmp_stex) {403state.tmp_stex = undefined; change(state, to_mode, {404mode: mode_stex, local: CodeMirror.startState(mode_stex)405});406}407break;408case 2:409change(state, to_explicit, context(rx_directive, 3));410if (stream.match(/^python\s*$/) || state.tmp_py) {411state.tmp_py = undefined; change(state, to_mode, {412mode: mode_python, local: CodeMirror.startState(mode_python)413});414}415break;416default:417change(state, to_normal);418}419} else if (phase(state) == rx_link || stream.match(rx_link, false)) {420421switch (stage(state)) {422case 0:423change(state, to_explicit, context(rx_link, 1));424stream.match(rx_link_head);425stream.match(rx_link_name);426token = 'link';427break;428case 1:429change(state, to_explicit, context(rx_link, 2));430stream.match(rx_link_tail);431token = 'meta';432break;433default:434change(state, to_normal);435}436} else if (stream.match(rx_footnote)) {437change(state, to_normal);438token = 'quote';439} else if (stream.match(rx_citation)) {440change(state, to_normal);441token = 'quote';442}443444else {445stream.eatSpace();446if (stream.eol()) {447change(state, to_normal);448} else {449stream.skipToEnd();450change(state, to_comment);451token = 'comment';452}453}454455return token;456}457458///////////////////////////////////////////////////////////////////////////459///////////////////////////////////////////////////////////////////////////460461function to_comment(stream, state) {462return as_block(stream, state, 'comment');463}464465function to_verbatim(stream, state) {466return as_block(stream, state, 'meta');467}468469function as_block(stream, state, token) {470if (stream.eol() || stream.eatSpace()) {471stream.skipToEnd();472return token;473} else {474change(state, to_normal);475return null;476}477}478479///////////////////////////////////////////////////////////////////////////480///////////////////////////////////////////////////////////////////////////481482function to_mode(stream, state) {483484if (state.ctx.mode && state.ctx.local) {485486if (stream.sol()) {487if (!stream.eatSpace()) change(state, to_normal);488return null;489}490491return state.ctx.mode.token(stream, state.ctx.local);492}493494change(state, to_normal);495return null;496}497498///////////////////////////////////////////////////////////////////////////499///////////////////////////////////////////////////////////////////////////500501function context(phase, stage, mode, local) {502return {phase: phase, stage: stage, mode: mode, local: local};503}504505function change(state, tok, ctx) {506state.tok = tok;507state.ctx = ctx || {};508}509510function stage(state) {511return state.ctx.stage || 0;512}513514function phase(state) {515return state.ctx.phase;516}517518///////////////////////////////////////////////////////////////////////////519///////////////////////////////////////////////////////////////////////////520521return {522startState: function () {523return {tok: to_normal, ctx: context(undefined, 0)};524},525526copyState: function (state) {527var ctx = state.ctx, tmp = state.tmp;528if (ctx.local)529ctx = {mode: ctx.mode, local: CodeMirror.copyState(ctx.mode, ctx.local)};530if (tmp)531tmp = {mode: tmp.mode, local: CodeMirror.copyState(tmp.mode, tmp.local)};532return {tok: state.tok, ctx: ctx, tmp: tmp};533},534535innerMode: function (state) {536return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode}537: state.ctx.mode ? {state: state.ctx.local, mode: state.ctx.mode}538: null;539},540541token: function (stream, state) {542return state.tok(stream, state);543}544};545}, 'python', 'stex');546547///////////////////////////////////////////////////////////////////////////////548///////////////////////////////////////////////////////////////////////////////549550CodeMirror.defineMIME('text/x-rst', 'rst');551552///////////////////////////////////////////////////////////////////////////////553///////////////////////////////////////////////////////////////////////////////554555556557