runmode.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. CodeMirror.runMode = function(string, modespec, callback, options) {
  2. function esc(str) {
  3. return str.replace(/[<&]/g, function(ch) { return ch == "<" ? "&lt;" : "&amp;"; });
  4. }
  5. var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
  6. var isNode = callback.nodeType == 1;
  7. var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
  8. if (isNode) {
  9. var node = callback, accum = [], col = 0;
  10. callback = function(text, style) {
  11. if (text == "\n") {
  12. accum.push("<br>");
  13. col = 0;
  14. return;
  15. }
  16. var escaped = "";
  17. // HTML-escape and replace tabs
  18. for (var pos = 0;;) {
  19. var idx = text.indexOf("\t", pos);
  20. if (idx == -1) {
  21. escaped += esc(text.slice(pos));
  22. col += text.length - pos;
  23. break;
  24. } else {
  25. col += idx - pos;
  26. escaped += esc(text.slice(pos, idx));
  27. var size = tabSize - col % tabSize;
  28. col += size;
  29. for (var i = 0; i < size; ++i) escaped += " ";
  30. pos = idx + 1;
  31. }
  32. }
  33. if (style)
  34. accum.push("<span class=\"cm-" + esc(style) + "\">" + escaped + "</span>");
  35. else
  36. accum.push(escaped);
  37. };
  38. }
  39. var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
  40. for (var i = 0, e = lines.length; i < e; ++i) {
  41. if (i) callback("\n");
  42. var stream = new CodeMirror.StringStream(lines[i]);
  43. while (!stream.eol()) {
  44. var style = mode.token(stream, state);
  45. callback(stream.current(), style, i, stream.start);
  46. stream.start = stream.pos;
  47. }
  48. }
  49. if (isNode)
  50. node.innerHTML = accum.join("");
  51. };