github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/app/public/codemirror/addon/runmode/runmode.node.js (about) 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: http://codemirror.net/LICENSE 3 4 /* Just enough of CodeMirror to run runMode under node.js */ 5 6 function splitLines(string){return string.split(/\r\n?|\n/);}; 7 8 // Counts the column offset in a string, taking tabs into account. 9 // Used mostly to find indentation. 10 var countColumn = function(string, end, tabSize, startIndex, startValue) { 11 if (end == null) { 12 end = string.search(/[^\s\u00a0]/); 13 if (end == -1) end = string.length; 14 } 15 for (var i = startIndex || 0, n = startValue || 0;;) { 16 var nextTab = string.indexOf("\t", i); 17 if (nextTab < 0 || nextTab >= end) 18 return n + (end - i); 19 n += nextTab - i; 20 n += tabSize - (n % tabSize); 21 i = nextTab + 1; 22 } 23 }; 24 25 function StringStream(string, tabSize) { 26 this.pos = this.start = 0; 27 this.string = string; 28 this.tabSize = tabSize || 8; 29 this.lastColumnPos = this.lastColumnValue = 0; 30 this.lineStart = 0; 31 }; 32 33 StringStream.prototype = { 34 eol: function() {return this.pos >= this.string.length;}, 35 sol: function() {return this.pos == this.lineStart;}, 36 peek: function() {return this.string.charAt(this.pos) || undefined;}, 37 next: function() { 38 if (this.pos < this.string.length) 39 return this.string.charAt(this.pos++); 40 }, 41 eat: function(match) { 42 var ch = this.string.charAt(this.pos); 43 if (typeof match == "string") var ok = ch == match; 44 else var ok = ch && (match.test ? match.test(ch) : match(ch)); 45 if (ok) {++this.pos; return ch;} 46 }, 47 eatWhile: function(match) { 48 var start = this.pos; 49 while (this.eat(match)){} 50 return this.pos > start; 51 }, 52 eatSpace: function() { 53 var start = this.pos; 54 while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; 55 return this.pos > start; 56 }, 57 skipToEnd: function() {this.pos = this.string.length;}, 58 skipTo: function(ch) { 59 var found = this.string.indexOf(ch, this.pos); 60 if (found > -1) {this.pos = found; return true;} 61 }, 62 backUp: function(n) {this.pos -= n;}, 63 column: function() { 64 if (this.lastColumnPos < this.start) { 65 this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); 66 this.lastColumnPos = this.start; 67 } 68 return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); 69 }, 70 indentation: function() { 71 return countColumn(this.string, null, this.tabSize) - 72 (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); 73 }, 74 match: function(pattern, consume, caseInsensitive) { 75 if (typeof pattern == "string") { 76 var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; 77 var substr = this.string.substr(this.pos, pattern.length); 78 if (cased(substr) == cased(pattern)) { 79 if (consume !== false) this.pos += pattern.length; 80 return true; 81 } 82 } else { 83 var match = this.string.slice(this.pos).match(pattern); 84 if (match && match.index > 0) return null; 85 if (match && consume !== false) this.pos += match[0].length; 86 return match; 87 } 88 }, 89 current: function(){return this.string.slice(this.start, this.pos);}, 90 hideFirstChars: function(n, inner) { 91 this.lineStart += n; 92 try { return inner(); } 93 finally { this.lineStart -= n; } 94 } 95 }; 96 exports.StringStream = StringStream; 97 98 exports.startState = function(mode, a1, a2) { 99 return mode.startState ? mode.startState(a1, a2) : true; 100 }; 101 102 var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; 103 exports.defineMode = function(name, mode) { 104 if (arguments.length > 2) 105 mode.dependencies = Array.prototype.slice.call(arguments, 2); 106 modes[name] = mode; 107 }; 108 exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; 109 110 exports.defineMode("null", function() { 111 return {token: function(stream) {stream.skipToEnd();}}; 112 }); 113 exports.defineMIME("text/plain", "null"); 114 115 exports.resolveMode = function(spec) { 116 if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { 117 spec = mimeModes[spec]; 118 } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { 119 spec = mimeModes[spec.name]; 120 } 121 if (typeof spec == "string") return {name: spec}; 122 else return spec || {name: "null"}; 123 }; 124 125 function copyObj(obj, target, overwrite) { 126 if (!target) target = {}; 127 for (var prop in obj) 128 if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) 129 target[prop] = obj[prop]; 130 return target; 131 } 132 133 // This can be used to attach properties to mode objects from 134 // outside the actual mode definition. 135 var modeExtensions = exports.modeExtensions = {}; 136 exports.extendMode = function(mode, properties) { 137 var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); 138 copyObj(properties, exts); 139 }; 140 141 exports.getMode = function(options, spec) { 142 var spec = exports.resolveMode(spec); 143 var mfactory = modes[spec.name]; 144 if (!mfactory) return exports.getMode(options, "text/plain"); 145 var modeObj = mfactory(options, spec); 146 if (modeExtensions.hasOwnProperty(spec.name)) { 147 var exts = modeExtensions[spec.name]; 148 for (var prop in exts) { 149 if (!exts.hasOwnProperty(prop)) continue; 150 if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; 151 modeObj[prop] = exts[prop]; 152 } 153 } 154 modeObj.name = spec.name; 155 if (spec.helperType) modeObj.helperType = spec.helperType; 156 if (spec.modeProps) for (var prop in spec.modeProps) 157 modeObj[prop] = spec.modeProps[prop]; 158 159 return modeObj; 160 }; 161 exports.registerHelper = exports.registerGlobalHelper = Math.min; 162 163 exports.runMode = function(string, modespec, callback, options) { 164 var mode = exports.getMode({indentUnit: 2}, modespec); 165 var lines = splitLines(string), state = (options && options.state) || exports.startState(mode); 166 for (var i = 0, e = lines.length; i < e; ++i) { 167 if (i) callback("\n"); 168 var stream = new exports.StringStream(lines[i]); 169 if (!stream.string && mode.blankLine) mode.blankLine(state); 170 while (!stream.eol()) { 171 var style = mode.token(stream, state); 172 callback(stream.current(), style, i, stream.start, state); 173 stream.start = stream.pos; 174 } 175 } 176 }; 177 178 require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]; 179 require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];