CodeMirror.defineMode("prism", function (config, parserConfig) { return { startState: function () { return {}; }, token: function (stream, state) { // Skip whitespace if (stream.eatSpace()) { return null; } // Single-line comments if (stream.match(/\/\/.*/)) { return "comment"; } // Check for module keyword and the identifier after it if (state.afterModule && stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) { state.afterModule = false; return "variable"; // Return token type for module names } // Check for module keyword and set state to look for identifier if (stream.match(/\bmodule\b/)) { state.afterModule = true; return "keyword"; // Return token type for keywords } // Keywords if ( stream.match( /\b(?:smg|mdp|dtmc|ctmc|pta|module|endmodule|player|endplayer|system|endsystem|invariant|endrewards|rewards|const|init|min|max|floor|ceil|round|pow|mod|log)\b/ ) ) { return "keyword"; } // Constants if (stream.match(/\b(?:true|false)\b/)) { return "atom"; } // Variable types if (stream.match(/\b(?:bool|double|int)\b/)) { return "keyword"; } // Variable definitions if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*\s*(?=[:=!'`])/)) { return "variable"; } // Strings if (stream.match(/"([^"\\]|\\.)*"/)) { return "string"; } // Operators if (stream.match(/[+\-*/|&<>!=]/)) { return "operator"; } // Numbers if (stream.match(/\b\d+(\.\d+)?\b/)) { return "number"; } // Handle other characters stream.next(); return null; }, startState: function () { return { afterModule: false, // Track whether we are looking for an identifier after a module keyword }; }, }; }); // Register the mode with a MIME type CodeMirror.defineMIME("text-x/myLanguage", "prism");