1 /* Just enough of CodeMirror to run runMode under node.js */
3 window
.CodeMirror
= {};
5 function splitLines(string
){ return string
.split(/\r?\n|\r/); };
7 function StringStream(string
) {
8 this.pos
= this.start
= 0;
11 StringStream
.prototype = {
12 eol: function() {return this.pos
>= this.string
.length
;},
13 sol: function() {return this.pos
== 0;},
14 peek: function() {return this.string
.charAt(this.pos
) || null;},
16 if (this.pos
< this.string
.length
)
17 return this.string
.charAt(this.pos
++);
19 eat: function(match
) {
20 var ch
= this.string
.charAt(this.pos
);
21 if (typeof match
== "string") var ok
= ch
== match
;
22 else var ok
= ch
&& (match
.test
? match
.test(ch
) : match(ch
));
23 if (ok
) {++this.pos
; return ch
;}
25 eatWhile: function(match
) {
27 while (this.eat(match
)){}
28 return this.pos
> start
;
30 eatSpace: function() {
32 while (/[\s\u00a0]/.test(this.string
.charAt(this.pos
))) ++this.pos
;
33 return this.pos
> start
;
35 skipToEnd: function() {this.pos
= this.string
.length
;},
36 skipTo: function(ch
) {
37 var found
= this.string
.indexOf(ch
, this.pos
);
38 if (found
> -1) {this.pos
= found
; return true;}
40 backUp: function(n
) {this.pos
-= n
;},
41 column: function() {return this.start
;},
42 indentation: function() {return 0;},
43 match: function(pattern
, consume
, caseInsensitive
) {
44 if (typeof pattern
== "string") {
45 var cased = function(str
) {return caseInsensitive
? str
.toLowerCase() : str
;};
46 if (cased(this.string
).indexOf(cased(pattern
), this.pos
) == this.pos
) {
47 if (consume
!== false) this.pos
+= pattern
.length
;
51 var match
= this.string
.slice(this.pos
).match(pattern
);
52 if (match
&& consume
!== false) this.pos
+= match
[0].length
;
56 current: function(){return this.string
.slice(this.start
, this.pos
);}
58 CodeMirror
.StringStream
= StringStream
;
60 CodeMirror
.startState = function (mode
, a1
, a2
) {
61 return mode
.startState
? mode
.startState(a1
, a2
) : true;
64 var modes
= CodeMirror
.modes
= {}, mimeModes
= CodeMirror
.mimeModes
= {};
65 CodeMirror
.defineMode = function (name
, mode
) { modes
[name
] = mode
; };
66 CodeMirror
.defineMIME = function (mime
, spec
) { mimeModes
[mime
] = spec
; };
67 CodeMirror
.getMode = function (options
, spec
) {
68 if (typeof spec
== "string" && mimeModes
.hasOwnProperty(spec
))
69 spec
= mimeModes
[spec
];
70 if (typeof spec
== "string")
71 var mname
= spec
, config
= {};
72 else if (spec
!= null)
73 var mname
= spec
.name
, config
= spec
;
74 var mfactory
= modes
[mname
];
75 if (!mfactory
) throw new Error("Unknown mode: " + spec
);
76 return mfactory(options
, config
|| {});
79 CodeMirror
.runMode = function (string
, modespec
, callback
, options
) {
80 var mode
= CodeMirror
.getMode({ indentUnit
: 2 }, modespec
);
82 if (callback
.nodeType
== 1) {
83 var tabSize
= (options
&& options
.tabSize
) || 4;
84 var node
= callback
, col
= 0;
86 callback = function (text
, style
) {
88 node
.appendChild(document
.createElement("br"));
94 for (var pos
= 0; ;) {
95 var idx
= text
.indexOf("\t", pos
);
97 content
+= text
.slice(pos
);
98 col
+= text
.length
- pos
;
102 content
+= text
.slice(pos
, idx
);
103 var size
= tabSize
- col
% tabSize
;
105 for (var i
= 0; i
< size
; ++i
) content
+= " ";
111 var sp
= node
.appendChild(document
.createElement("span"));
112 sp
.className
= "cm-" + style
.replace(/ +/g
, " cm-");
113 sp
.appendChild(document
.createTextNode(content
));
115 node
.appendChild(document
.createTextNode(content
));
120 var lines
= splitLines(string
), state
= CodeMirror
.startState(mode
);
121 for (var i
= 0, e
= lines
.length
; i
< e
; ++i
) {
122 if (i
) callback("\n");
123 var stream
= new CodeMirror
.StringStream(lines
[i
]);
124 while (!stream
.eol()) {
125 var style
= mode
.token(stream
, state
);
126 callback(stream
.current(), style
, i
, stream
.start
);
127 stream
.start
= stream
.pos
;