jade.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. (function(mod) {
  2. if (typeof exports == "object" && typeof module == "object") // CommonJS
  3. mod(require("../../lib/codemirror"));
  4. else if (typeof define == "function" && define.amd) // AMD
  5. define(["../../lib/codemirror"], mod);
  6. else // Plain browser env
  7. mod(CodeMirror);
  8. })(function(CodeMirror) {
  9. "use strict";
  10. CodeMirror.defineMode("jade", function () {
  11. var symbol_regex1 = /^(?:~|!|%|\^|\*|\+|=|\\|:|;|,|\/|\?|&|<|>|\|)/;
  12. var open_paren_regex = /^(\(|\[)/;
  13. var close_paren_regex = /^(\)|\])/;
  14. var keyword_regex1 = /^(if|else|return|var|function|include|doctype|each)/;
  15. var keyword_regex2 = /^(#|{|}|\.)/;
  16. var keyword_regex3 = /^(in)/;
  17. var html_regex1 = /^(html|head|title|meta|link|script|body|br|div|input|span|a|img)/;
  18. var html_regex2 = /^(h1|h2|h3|h4|h5|p|strong|em)/;
  19. return {
  20. startState: function () {
  21. return {
  22. inString: false,
  23. stringType: "",
  24. beforeTag: true,
  25. justMatchedKeyword: false,
  26. afterParen: false
  27. };
  28. },
  29. token: function (stream, state) {
  30. //check for state changes
  31. if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
  32. state.stringType = stream.peek();
  33. stream.next(); // Skip quote
  34. state.inString = true; // Update state
  35. }
  36. //return state
  37. if (state.inString) {
  38. if (stream.skipTo(state.stringType)) { // Quote found on this line
  39. stream.next(); // Skip quote
  40. state.inString = false; // Clear flag
  41. } else {
  42. stream.skipToEnd(); // Rest of line is string
  43. }
  44. state.justMatchedKeyword = false;
  45. return "string"; // Token style
  46. } else if (stream.sol() && stream.eatSpace()) {
  47. if (stream.match(keyword_regex1)) {
  48. state.justMatchedKeyword = true;
  49. stream.eatSpace();
  50. return "keyword";
  51. }
  52. if (stream.match(html_regex1) || stream.match(html_regex2)) {
  53. state.justMatchedKeyword = true;
  54. return "variable";
  55. }
  56. } else if (stream.sol() && stream.match(keyword_regex1)) {
  57. state.justMatchedKeyword = true;
  58. stream.eatSpace();
  59. return "keyword";
  60. } else if (stream.sol() && (stream.match(html_regex1) || stream.match(html_regex2))) {
  61. state.justMatchedKeyword = true;
  62. return "variable";
  63. } else if (stream.eatSpace()) {
  64. state.justMatchedKeyword = false;
  65. if (stream.match(keyword_regex3) && stream.eatSpace()) {
  66. state.justMatchedKeyword = true;
  67. return "keyword";
  68. }
  69. } else if (stream.match(symbol_regex1)) {
  70. state.justMatchedKeyword = false;
  71. return "atom";
  72. } else if (stream.match(open_paren_regex)) {
  73. state.afterParen = true;
  74. state.justMatchedKeyword = true;
  75. return "def";
  76. } else if (stream.match(close_paren_regex)) {
  77. state.afterParen = false;
  78. state.justMatchedKeyword = true;
  79. return "def";
  80. } else if (stream.match(keyword_regex2)) {
  81. state.justMatchedKeyword = true;
  82. return "keyword";
  83. } else if (stream.eatSpace()) {
  84. state.justMatchedKeyword = false;
  85. } else {
  86. stream.next();
  87. if (state.justMatchedKeyword) {
  88. return "property";
  89. } else if (state.afterParen) {
  90. return "property";
  91. }
  92. }
  93. return null;
  94. }
  95. };
  96. });
  97. CodeMirror.defineMIME('text/x-jade', 'jade');
  98. });