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/custom-modes.ts
Views: 687
//########################################################################1// This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2// License: MS-RSL – see LICENSE.md for details3//########################################################################45// Multiplex'd worksheet mode67import { MARKERS } from "@cocalc/util/sagews";8import { clone, object } from "underscore";9import CodeMirror from "./codemirror";10import "codemirror/addon/mode/multiplex";11import "./multiplex";1213export const sagews_decorator_modes: [string, string][] = [14["cjsx", "text/cjsx"],15["coffeescript", "coffeescript"],16["cython", "cython"],17["file", "text"],18["fortran", "text/x-fortran"],19["html", "htmlmixed"],20["javascript", "javascript"],21["java", "text/x-java"], // !! more specific name must be first!!!! (java vs javascript!)22["latex", "stex"],23["lisp", "ecl"],24["md", "gfm2"],25["gp", "text/pari"],26["go", "text/x-go"],27["perl", "text/x-perl"],28["python3", "python"],29["python", "python"],30["ruby", "text/x-ruby"], // !! more specific name must be first or get mismatch!31["r", "r"],32["sage", "python"],33["script", "shell"],34["sh", "shell"],35["julia", "text/x-julia"],36["wiki", "mediawiki"],37["mediawiki", "mediawiki"],38];3940// Many of the modes below are multiplexed4142interface MultiplexOption {43open: string | RegExp;44close: string | RegExp;45mode: unknown;46start?: boolean;47delimStyle?: string;48}4950// not using these two gfm2 and htmlmixed2 modes, with their sub-latex mode, since51// detection of math isn't good enough. e.g., \$ causes math mode and $ doesn't seem to... \$500 and $\sin(x)$.5253CodeMirror.defineMode("gfm2", function (config) {54const options: MultiplexOption[] = [];55for (let x of [56["$$", "$$"],57["$", "$"],58["\\[", "\\]"],59["\\(", "\\)"],60]) {61options.push({62open: x[0],63close: x[1],64mode: CodeMirror.getMode(config, "stex"),65});66}67return (CodeMirror as any).multiplexingMode(68CodeMirror.getMode(config, "gfm"),69...options70);71});7273CodeMirror.defineMode("htmlmixed2", function (config) {74const options: MultiplexOption[] = [];75for (let x of [76["$$", "$$"],77["$", "$"],78["\\[", "\\]"],79["\\(", "\\)"],80]) {81options.push({82open: x[0],83close: x[1],84mode: CodeMirror.getMode(config, "stex"),85});86}87return (CodeMirror as any).multiplexingMode(88CodeMirror.getMode(config, "htmlmixed"),89...options90);91});9293CodeMirror.defineMode("stex2", function (config) {94const options: MultiplexOption[] = [];95for (let x of ["sagesilent", "sageblock"]) {96options.push({97open: `\\begin{${x}}`,98close: `\\end{${x}}`,99mode: CodeMirror.getMode(config, "sagews"),100});101}102options.push({103open: "\\sage{",104close: "}",105mode: CodeMirror.getMode(config, "sagews"),106});107return (CodeMirror as any).multiplexingMode(108CodeMirror.getMode(config, "stex"),109...options110);111});112113CodeMirror.defineMode("rnw", function (config) {114const block = {115open: /^<<.+?>>=/,116close: /^@/,117mode: CodeMirror.getMode(config, "r"),118};119const inline = {120open: "\\Sexpr{",121close: "}",122mode: CodeMirror.getMode(config, "r"),123};124return (CodeMirror as any).multiplexingMode(125CodeMirror.getMode(config, "stex2"),126block,127inline128);129});130131CodeMirror.defineMode("rtex", function (config) {132const block = {133open: /^%%\s+begin\.rcode/,134close: /^%%\s+end\.rcode/,135indent: "% ",136mode: CodeMirror.getMode(config, "r"),137};138const inline = {139open: "\\rinline{",140close: "}",141mode: CodeMirror.getMode(config, "r"),142};143return (CodeMirror as any).multiplexingMode(144CodeMirror.getMode(config, "stex2"),145block,146inline147);148});149150CodeMirror.defineMode("cython", (config) => {151// FUTURE: need to figure out how to do this so that the name152// of the mode is cython153return (CodeMirror as any).multiplexingMode(154CodeMirror.getMode(config, "python")155);156});157158CodeMirror.defineMode("mojo", (config) => {159// FUTURE: need to figure out how to do this so that the name160// of the mode is mojo or modular161return (CodeMirror as any).multiplexingMode(162CodeMirror.getMode(config, "python")163);164});165166CodeMirror.defineMode("sagews", function (config) {167const options: MultiplexOption[] = [];168const close = new RegExp(`[${MARKERS.output}${MARKERS.cell}]`);169for (const x of sagews_decorator_modes) {170// NOTE: very important to close on both MARKERS.output *and* MARKERS.cell,171// rather than just MARKERS.cell, or it will try to172// highlight the *hidden* output message line, which can173// be *enormous*, and could take a very very long time, but is174// a complete waste, since we never see that markup.175options.push({176open: "%" + x[0],177start: true, // must be at beginning of line178close,179mode: CodeMirror.getMode(config, x[1]),180});181}182183return (CodeMirror as any).cocalcMultiplexingMode(184CodeMirror.getMode(config, "python"),185...options186);187});188189CodeMirror.defineMode("rmd", function (config) {190// derived from the sagews modes with some additions191let mode, open;192const modes = clone(object(sagews_decorator_modes));193modes["fortran95"] = modes["fortran"];194modes["octave"] = "octave";195modes["bash"] = modes["sh"];196197const options: MultiplexOption[] = [];198199// blocks (ATTN ruby before r!)200// all engine modes: names(knitr::knit_engines$get())201for (let name of [202"ruby",203"r",204"python",205"octave",206"fortran95",207"fortran",208"octave",209"bash",210"go",211"julia",212"perl",213]) {214mode = modes[name];215open = new RegExp(`\`\`\`\\s*{${name}[^}]*?}`);216options.push({217open,218close: "```",219delimStyle: "gfm",220mode: CodeMirror.getMode(config, mode),221});222}223224// ATTN: this case must come later, it is less specific225// inline, just `r ...` exists, not for other languages.226options.push({227open: "`r",228close: "`",229mode: CodeMirror.getMode(config, "r"),230});231232return (CodeMirror as any).multiplexingMode(233CodeMirror.getMode(config, "yaml-frontmatter"),234...options235);236});237238239