1 /* Just enough of CodeMirror to run runMode under node.js */
3 function splitLines(string
){ return string
.split(/\r?\n|\r/); };
5 function StringStream(string
) {
6 this.pos
= this.start
= 0;
9 StringStream
.prototype = {
10 eol: function() {return this.pos
>= this.string
.length
;},
11 sol: function() {return this.pos
== 0;},
12 peek: function() {return this.string
.charAt(this.pos
) || null;},
14 if (this.pos
< this.string
.length
)
15 return this.string
.charAt(this.pos
++);
17 eat: function(match
) {
18 var ch
= this.string
.charAt(this.pos
);
19 if (typeof match
== "string") var ok
= ch
== match
;
20 else var ok
= ch
&& (match
.test
? match
.test(ch
) : match(ch
));
21 if (ok
) {++this.pos
; return ch
;}
23 eatWhile: function(match
) {
25 while (this.eat(match
)){}
26 return this.pos
> start
;
28 eatSpace: function() {
30 while (/[\s\u00a0]/.test(this.string
.charAt(this.pos
))) ++this.pos
;
31 return this.pos
> start
;
33 skipToEnd: function() {this.pos
= this.string
.length
;},
34 skipTo: function(ch
) {
35 var found
= this.string
.indexOf(ch
, this.pos
);
36 if (found
> -1) {this.pos
= found
; return true;}
38 backUp: function(n
) {this.pos
-= n
;},
39 column: function() {return this.start
;},
40 indentation: function() {return 0;},
41 match: function(pattern
, consume
, caseInsensitive
) {
42 if (typeof pattern
== "string") {
43 var cased = function(str
) {return caseInsensitive
? str
.toLowerCase() : str
;};
44 if (cased(this.string
).indexOf(cased(pattern
), this.pos
) == this.pos
) {
45 if (consume
!== false) this.pos
+= pattern
.length
;
49 var match
= this.string
.slice(this.pos
).match(pattern
);
50 if (match
&& consume
!== false) this.pos
+= match
[0].length
;
54 current: function(){return this.string
.slice(this.start
, this.pos
);}
56 exports
.StringStream
= StringStream
;
58 exports
.startState = function(mode
, a1
, a2
) {
59 return mode
.startState
? mode
.startState(a1
, a2
) : true;
62 var modes
= exports
.modes
= {}, mimeModes
= exports
.mimeModes
= {};
63 exports
.defineMode = function(name
, mode
) {
64 if (arguments
.length
> 2) {
65 mode
.dependencies
= [];
66 for (var i
= 2; i
< arguments
.length
; ++i
) mode
.dependencies
.push(arguments
[i
]);
70 exports
.defineMIME = function(mime
, spec
) { mimeModes
[mime
] = spec
; };
72 exports
.defineMode("null", function() {
73 return {token: function(stream
) {stream
.skipToEnd();}};
75 exports
.defineMIME("text/plain", "null");
77 exports
.getMode = function(options
, spec
) {
78 if (typeof spec
== "string" && mimeModes
.hasOwnProperty(spec
))
79 spec
= mimeModes
[spec
];
80 if (typeof spec
== "string")
81 var mname
= spec
, config
= {};
82 else if (spec
!= null)
83 var mname
= spec
.name
, config
= spec
;
84 var mfactory
= modes
[mname
];
85 if (!mfactory
) throw new Error("Unknown mode: " + spec
);
86 return mfactory(options
, config
|| {});
89 exports
.runMode = function(string
, modespec
, callback
) {
90 var mode
= exports
.getMode({indentUnit
: 2}, modespec
);
91 var lines
= splitLines(string
), state
= exports
.startState(mode
);
92 for (var i
= 0, e
= lines
.length
; i
< e
; ++i
) {
93 if (i
) callback("\n");
94 var stream
= new exports
.StringStream(lines
[i
]);
95 while (!stream
.eol()) {
96 var style
= mode
.token(stream
, state
);
97 callback(stream
.current(), style
, i
, stream
.start
);
98 stream
.start
= stream
.pos
;