|
| 1 | +CodeMirror.defineMode("python",function(conf,parserConf){ |
| 2 | +varERRORCLASS='error'; |
| 3 | + |
| 4 | +functionwordRegexp(words){ |
| 5 | +returnnewRegExp("^(("+words.join(")|(")+"))\\b"); |
| 6 | +} |
| 7 | + |
| 8 | +varsingleOperators=parserConf.singleOperators||newRegExp("^[\\+\\-\\*/%&|\\^~<>!]"); |
| 9 | +varsingleDelimiters=parserConf.singleDelimiters||newRegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]'); |
| 10 | +vardoubleOperators=parserConf.doubleOperators||newRegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); |
| 11 | +vardoubleDelimiters=parserConf.doubleDelimiters||newRegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); |
| 12 | +vartripleDelimiters=parserConf.tripleDelimiters||newRegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"); |
| 13 | +varidentifiers=parserConf.identifiers||newRegExp("^[_A-Za-z][_A-Za-z0-9]*"); |
| 14 | + |
| 15 | +varwordOperators=wordRegexp(['and','or','not','is','in']); |
| 16 | +varcommonkeywords=['as','assert','break','class','continue', |
| 17 | +'def','del','elif','else','except','finally', |
| 18 | +'for','from','global','if','import', |
| 19 | +'lambda','pass','raise','return', |
| 20 | +'try','while','with','yield']; |
| 21 | +varcommonBuiltins=['abs','all','any','bin','bool','bytearray','callable','chr', |
| 22 | +'classmethod','compile','complex','delattr','dict','dir','divmod', |
| 23 | +'enumerate','eval','filter','float','format','frozenset', |
| 24 | +'getattr','globals','hasattr','hash','help','hex','id', |
| 25 | +'input','int','isinstance','issubclass','iter','len', |
| 26 | +'list','locals','map','max','memoryview','min','next', |
| 27 | +'object','oct','open','ord','pow','property','range', |
| 28 | +'repr','reversed','round','set','setattr','slice', |
| 29 | +'sorted','staticmethod','str','sum','super','tuple', |
| 30 | +'type','vars','zip','__import__','NotImplemented', |
| 31 | +'Ellipsis','__debug__']; |
| 32 | +varpy2={'builtins': ['apply','basestring','buffer','cmp','coerce','execfile', |
| 33 | +'file','intern','long','raw_input','reduce','reload', |
| 34 | +'unichr','unicode','xrange','False','True','None'], |
| 35 | +'keywords': ['exec','print']}; |
| 36 | +varpy3={'builtins': ['ascii','bytes','exec','print'], |
| 37 | +'keywords': ['nonlocal','False','True','None']}; |
| 38 | + |
| 39 | +if(parserConf.extra_keywords!=undefined){ |
| 40 | +commonkeywords=commonkeywords.concat(parserConf.extra_keywords); |
| 41 | +} |
| 42 | +if(parserConf.extra_builtins!=undefined){ |
| 43 | +commonBuiltins=commonBuiltins.concat(parserConf.extra_builtins); |
| 44 | +} |
| 45 | +if(!!parserConf.version&&parseInt(parserConf.version,10)===3){ |
| 46 | +commonkeywords=commonkeywords.concat(py3.keywords); |
| 47 | +commonBuiltins=commonBuiltins.concat(py3.builtins); |
| 48 | +varstringPrefixes=newRegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))","i"); |
| 49 | +}else{ |
| 50 | +commonkeywords=commonkeywords.concat(py2.keywords); |
| 51 | +commonBuiltins=commonBuiltins.concat(py2.builtins); |
| 52 | +varstringPrefixes=newRegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))","i"); |
| 53 | +} |
| 54 | +varkeywords=wordRegexp(commonkeywords); |
| 55 | +varbuiltins=wordRegexp(commonBuiltins); |
| 56 | + |
| 57 | +varindentInfo=null; |
| 58 | + |
| 59 | +// tokenizers |
| 60 | +functiontokenBase(stream,state){ |
| 61 | +// Handle scope changes |
| 62 | +if(stream.sol()){ |
| 63 | +varscopeOffset=state.scopes[0].offset; |
| 64 | +if(stream.eatSpace()){ |
| 65 | +varlineOffset=stream.indentation(); |
| 66 | +if(lineOffset>scopeOffset){ |
| 67 | +indentInfo='indent'; |
| 68 | +}elseif(lineOffset<scopeOffset){ |
| 69 | +indentInfo='dedent'; |
| 70 | +} |
| 71 | +returnnull; |
| 72 | +}else{ |
| 73 | +if(scopeOffset>0){ |
| 74 | +dedent(stream,state); |
| 75 | +} |
| 76 | +} |
| 77 | +} |
| 78 | +if(stream.eatSpace()){ |
| 79 | +returnnull; |
| 80 | +} |
| 81 | + |
| 82 | +varch=stream.peek(); |
| 83 | + |
| 84 | +// Handle Comments |
| 85 | +if(ch==='#'){ |
| 86 | +stream.skipToEnd(); |
| 87 | +return'comment'; |
| 88 | +} |
| 89 | + |
| 90 | +// Handle Number Literals |
| 91 | +if(stream.match(/^[0-9\.]/,false)){ |
| 92 | +varfloatLiteral=false; |
| 93 | +// Floats |
| 94 | +if(stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)){floatLiteral=true;} |
| 95 | +if(stream.match(/^\d+\.\d*/)){floatLiteral=true;} |
| 96 | +if(stream.match(/^\.\d+/)){floatLiteral=true;} |
| 97 | +if(floatLiteral){ |
| 98 | +// Float literals may be "imaginary" |
| 99 | +stream.eat(/J/i); |
| 100 | +return'number'; |
| 101 | +} |
| 102 | +// Integers |
| 103 | +varintLiteral=false; |
| 104 | +// Hex |
| 105 | +if(stream.match(/^0x[0-9a-f]+/i)){intLiteral=true;} |
| 106 | +// Binary |
| 107 | +if(stream.match(/^0b[01]+/i)){intLiteral=true;} |
| 108 | +// Octal |
| 109 | +if(stream.match(/^0o[0-7]+/i)){intLiteral=true;} |
| 110 | +// Decimal |
| 111 | +if(stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)){ |
| 112 | +// Decimal literals may be "imaginary" |
| 113 | +stream.eat(/J/i); |
| 114 | +// TODO - Can you have imaginary longs? |
| 115 | +intLiteral=true; |
| 116 | +} |
| 117 | +// Zero by itself with no other piece of number. |
| 118 | +if(stream.match(/^0(?![\dx])/i)){intLiteral=true;} |
| 119 | +if(intLiteral){ |
| 120 | +// Integer literals may be "long" |
| 121 | +stream.eat(/L/i); |
| 122 | +return'number'; |
| 123 | +} |
| 124 | +} |
| 125 | + |
| 126 | +// Handle Strings |
| 127 | +if(stream.match(stringPrefixes)){ |
| 128 | +state.tokenize=tokenStringFactory(stream.current()); |
| 129 | +returnstate.tokenize(stream,state); |
| 130 | +} |
| 131 | + |
| 132 | +// Handle operators and Delimiters |
| 133 | +if(stream.match(tripleDelimiters)||stream.match(doubleDelimiters)){ |
| 134 | +returnnull; |
| 135 | +} |
| 136 | +if(stream.match(doubleOperators) |
| 137 | +||stream.match(singleOperators) |
| 138 | +||stream.match(wordOperators)){ |
| 139 | +return'operator'; |
| 140 | +} |
| 141 | +if(stream.match(singleDelimiters)){ |
| 142 | +returnnull; |
| 143 | +} |
| 144 | + |
| 145 | +if(stream.match(keywords)){ |
| 146 | +return'keyword'; |
| 147 | +} |
| 148 | + |
| 149 | +if(stream.match(builtins)){ |
| 150 | +return'builtin'; |
| 151 | +} |
| 152 | + |
| 153 | +if(stream.match(identifiers)){ |
| 154 | +if(state.lastToken=='def'||state.lastToken=='class'){ |
| 155 | +return'def'; |
| 156 | +} |
| 157 | +return'variable'; |
| 158 | +} |
| 159 | + |
| 160 | +// Handle non-detected items |
| 161 | +stream.next(); |
| 162 | +returnERRORCLASS; |
| 163 | +} |
| 164 | + |
| 165 | +functiontokenStringFactory(delimiter){ |
| 166 | +while('rub'.indexOf(delimiter.charAt(0).toLowerCase())>=0){ |
| 167 | +delimiter=delimiter.substr(1); |
| 168 | +} |
| 169 | +varsingleline=delimiter.length==1; |
| 170 | +varOUTCLASS='string'; |
| 171 | + |
| 172 | +functiontokenString(stream,state){ |
| 173 | +while(!stream.eol()){ |
| 174 | +stream.eatWhile(/[^'"\\]/); |
| 175 | +if(stream.eat('\\')){ |
| 176 | +stream.next(); |
| 177 | +if(singleline&&stream.eol()){ |
| 178 | +returnOUTCLASS; |
| 179 | +} |
| 180 | +}elseif(stream.match(delimiter)){ |
| 181 | +state.tokenize=tokenBase; |
| 182 | +returnOUTCLASS; |
| 183 | +}else{ |
| 184 | +stream.eat(/['"]/); |
| 185 | +} |
| 186 | +} |
| 187 | +if(singleline){ |
| 188 | +if(parserConf.singleLineStringErrors){ |
| 189 | +returnERRORCLASS; |
| 190 | +}else{ |
| 191 | +state.tokenize=tokenBase; |
| 192 | +} |
| 193 | +} |
| 194 | +returnOUTCLASS; |
| 195 | +} |
| 196 | +tokenString.isString=true; |
| 197 | +returntokenString; |
| 198 | +} |
| 199 | + |
| 200 | +functionindent(stream,state,type){ |
| 201 | +type=type||'py'; |
| 202 | +varindentUnit=0; |
| 203 | +if(type==='py'){ |
| 204 | +if(state.scopes[0].type!=='py'){ |
| 205 | +state.scopes[0].offset=stream.indentation(); |
| 206 | +return; |
| 207 | +} |
| 208 | +for(vari=0;i<state.scopes.length;++i){ |
| 209 | +if(state.scopes[i].type==='py'){ |
| 210 | +indentUnit=state.scopes[i].offset+conf.indentUnit; |
| 211 | +break; |
| 212 | +} |
| 213 | +} |
| 214 | +}else{ |
| 215 | +indentUnit=stream.column()+stream.current().length; |
| 216 | +} |
| 217 | +state.scopes.unshift({ |
| 218 | +offset: indentUnit, |
| 219 | +type: type |
| 220 | +}); |
| 221 | +} |
| 222 | + |
| 223 | +functiondedent(stream,state,type){ |
| 224 | +type=type||'py'; |
| 225 | +if(state.scopes.length==1)return; |
| 226 | +if(state.scopes[0].type==='py'){ |
| 227 | +var_indent=stream.indentation(); |
| 228 | +var_indent_index=-1; |
| 229 | +for(vari=0;i<state.scopes.length;++i){ |
| 230 | +if(_indent===state.scopes[i].offset){ |
| 231 | +_indent_index=i; |
| 232 | +break; |
| 233 | +} |
| 234 | +} |
| 235 | +if(_indent_index===-1){ |
| 236 | +returntrue; |
| 237 | +} |
| 238 | +while(state.scopes[0].offset!==_indent){ |
| 239 | +state.scopes.shift(); |
| 240 | +} |
| 241 | +returnfalse; |
| 242 | +}else{ |
| 243 | +if(type==='py'){ |
| 244 | +state.scopes[0].offset=stream.indentation(); |
| 245 | +returnfalse; |
| 246 | +}else{ |
| 247 | +if(state.scopes[0].type!=type){ |
| 248 | +returntrue; |
| 249 | +} |
| 250 | +state.scopes.shift(); |
| 251 | +returnfalse; |
| 252 | +} |
| 253 | +} |
| 254 | +} |
| 255 | + |
| 256 | +functiontokenLexer(stream,state){ |
| 257 | +indentInfo=null; |
| 258 | +varstyle=state.tokenize(stream,state); |
| 259 | +varcurrent=stream.current(); |
| 260 | + |
| 261 | +// Handle '.' connected identifiers |
| 262 | +if(current==='.'){ |
| 263 | +style=stream.match(identifiers,false) ? null : ERRORCLASS; |
| 264 | +if(style===null&&state.lastStyle==='meta'){ |
| 265 | +// Apply 'meta' style to '.' connected identifiers when |
| 266 | +// appropriate. |
| 267 | +style='meta'; |
| 268 | +} |
| 269 | +returnstyle; |
| 270 | +} |
| 271 | + |
| 272 | +// Handle decorators |
| 273 | +if(current==='@'){ |
| 274 | +returnstream.match(identifiers,false) ? 'meta' : ERRORCLASS; |
| 275 | +} |
| 276 | + |
| 277 | +if((style==='variable'||style==='builtin') |
| 278 | +&&state.lastStyle==='meta'){ |
| 279 | +style='meta'; |
| 280 | +} |
| 281 | + |
| 282 | +// Handle scope changes. |
| 283 | +if(current==='pass'||current==='return'){ |
| 284 | +state.dedent+=1; |
| 285 | +} |
| 286 | +if(current==='lambda')state.lambda=true; |
| 287 | +if((current===':'&&!state.lambda&&state.scopes[0].type=='py') |
| 288 | +||indentInfo==='indent'){ |
| 289 | +indent(stream,state); |
| 290 | +} |
| 291 | +vardelimiter_index='[({'.indexOf(current); |
| 292 | +if(delimiter_index!==-1){ |
| 293 | +indent(stream,state,'])}'.slice(delimiter_index,delimiter_index+1)); |
| 294 | +} |
| 295 | +if(indentInfo==='dedent'){ |
| 296 | +if(dedent(stream,state)){ |
| 297 | +returnERRORCLASS; |
| 298 | +} |
| 299 | +} |
| 300 | +delimiter_index='])}'.indexOf(current); |
| 301 | +if(delimiter_index!==-1){ |
| 302 | +if(dedent(stream,state,current)){ |
| 303 | +returnERRORCLASS; |
| 304 | +} |
| 305 | +} |
| 306 | +if(state.dedent>0&&stream.eol()&&state.scopes[0].type=='py'){ |
| 307 | +if(state.scopes.length>1)state.scopes.shift(); |
| 308 | +state.dedent-=1; |
| 309 | +} |
| 310 | + |
| 311 | +returnstyle; |
| 312 | +} |
| 313 | + |
| 314 | +varexternal={ |
| 315 | +startState: function(basecolumn){ |
| 316 | +return{ |
| 317 | +tokenize: tokenBase, |
| 318 | +scopes: [{offset:basecolumn||0,type:'py'}], |
| 319 | +lastStyle: null, |
| 320 | +lastToken: null, |
| 321 | +lambda: false, |
| 322 | +dedent: 0 |
| 323 | +}; |
| 324 | +}, |
| 325 | + |
| 326 | +token: function(stream,state){ |
| 327 | +varstyle=tokenLexer(stream,state); |
| 328 | + |
| 329 | +state.lastStyle=style; |
| 330 | + |
| 331 | +varcurrent=stream.current(); |
| 332 | +if(current&&style){ |
| 333 | +state.lastToken=current; |
| 334 | +} |
| 335 | + |
| 336 | +if(stream.eol()&&state.lambda){ |
| 337 | +state.lambda=false; |
| 338 | +} |
| 339 | +returnstyle; |
| 340 | +}, |
| 341 | + |
| 342 | +indent: function(state){ |
| 343 | +if(state.tokenize!=tokenBase){ |
| 344 | +returnstate.tokenize.isString ? CodeMirror.Pass : 0; |
| 345 | +} |
| 346 | + |
| 347 | +returnstate.scopes[0].offset; |
| 348 | +}, |
| 349 | + |
| 350 | +lineComment: "#", |
| 351 | +fold: "indent" |
| 352 | +}; |
| 353 | +returnexternal; |
| 354 | +}); |
| 355 | + |
| 356 | +CodeMirror.defineMIME("text/x-python","python"); |
| 357 | + |
| 358 | +(function(){ |
| 359 | +"use strict"; |
| 360 | +varwords=function(str){returnstr.split(' ');}; |
| 361 | + |
| 362 | +CodeMirror.defineMIME("text/x-cython",{ |
| 363 | +name: "python", |
| 364 | +extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+ |
| 365 | +"extern gil include nogil property public"+ |
| 366 | +"readonly struct union DEF IF ELIF ELSE") |
| 367 | +}); |
| 368 | +})(); |
0 commit comments