1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | CodeMirror.defineMode("pascal", function(config) { function words(str) { var obj = {}, words = str.split(" "); for (var i = 0; i < words.length; ++i) obj[words[i]] = true; return obj; } var keywords = words("and array begin case const div do downto else end file for forward integer " + "boolean char function goto if in label mod nil not of or packed procedure " + "program record repeat set string then to type until var while with"); var blockKeywords = words("case do else for if switch while struct then of"); var atoms = {"null": true}; var isOperatorChar = /[+\-*&%=<>!?|\/]/; var curPunc; function tokenBase(stream, state) { var ch = stream.next(); if (ch == "#" && state.startOfLine) { stream.skipToEnd(); return "meta"; } if (ch == '"' || ch == "'") { state.tokenize = tokenString(ch); return state.tokenize(stream, state); } if (ch == "(" && stream.eat("*")) { state.tokenize = tokenComment; return tokenComment(stream, state); } if (/[\[\]{}\(\),;\:\.]/.test(ch)) { curPunc = ch; return null } if (/\d/.test(ch)) { stream.eatWhile(/[\w\.]/); return "number"; } if (ch == "/") { if (stream.eat("/")) { stream.skipToEnd(); return "comment"; } } if (isOperatorChar.test(ch)) { stream.eatWhile(isOperatorChar); return "operator"; } stream.eatWhile(/[\w\$_]/); var cur = stream.current(); if (keywords.propertyIsEnumerable(cur)) { if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; return "keyword"; } if (atoms.propertyIsEnumerable(cur)) return "atom"; return "word"; } function tokenString(quote) { return function(stream, state) { var escaped = false, next, end = false; while ((next = stream.next()) != null) { if (next == quote && !escaped) {end = true; break;} escaped = !escaped && next == "\\"; } if (end || !escaped) state.tokenize = null; return "string"; }; } function tokenComment(stream, state) { var maybeEnd = false, ch; while (ch = stream.next()) { if (ch == ")" && maybeEnd) { state.tokenize = null; break; } maybeEnd = (ch == "*"); } return "comment"; } function Context(indented, column, type, align, prev) { this.indented = indented; this.column = column; this.type = type; this.align = align; this.prev = prev; } function pushContext(state, col, type) { return state.context = new Context(state.indented, col, type, null, state.context); } function popContext(state) { var t = state.context.type; if (t == ")" || t == "]" ) state.indented = state.context.indented; return state.context = state.context.prev; } // Interface return { startState: function(basecolumn) { return { tokenize: null, context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false), indented: 0, startOfLine: true }; }, token: function(stream, state) { var ctx = state.context; if (stream.sol()) { if (ctx.align == null) ctx.align = false; state.indented = stream.indentation(); state.startOfLine = true; } if (stream.eatSpace()) return null; curPunc = null; var style = (state.tokenize || tokenBase)(stream, state); if (style == "comment" || style == "meta") return style; if (ctx.align == null) ctx.align = true; if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state); else if (curPunc == "[") pushContext(state, stream.column(), "]"); else if (curPunc == "(") pushContext(state, stream.column(), ")"); else if (curPunc == ctx.type) popContext(state); else if ( ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement")) pushContext(state, stream.column(), "statement"); state.startOfLine = false; return style; }, electricChars: "{}" }; }); CodeMirror.defineMIME("text/x-pascal", "pascal"); |