parser.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. var fs = require('fs');
  2. var path = require('path');
  3. function parse(loader, source, context, cb) {
  4. var imports = [];
  5. var importPattern = /@import ([.\/\w_-]+);/gi;
  6. var match = importPattern.exec(source);
  7. while (match != null) {
  8. imports.push({
  9. key: match[1],
  10. target: match[0],
  11. content: ''
  12. });
  13. match = importPattern.exec(source);
  14. }
  15. source = uncomment(source);
  16. processImports(loader, source, context, imports, cb);
  17. }
  18. var singleComment = 1;
  19. var multiComment = 2;
  20. function uncomment(str) {
  21. var currentChar;
  22. var nextChar;
  23. var insideString = false;
  24. var insideComment = 0;
  25. var offset = 0;
  26. var ret = '';
  27. str = str.replace(/\r\n/g, '\n');
  28. str = str.replace(/[ \f\t\v]+/g, ' ');
  29. str = str.replace(/^\s*\n/gm, '');
  30. str = str.replace(/ \+ /g, '+');
  31. str = str.replace(/ \- /g, '-');
  32. str = str.replace(/ \/ /g, '/');
  33. str = str.replace(/ \* /g, '*');
  34. str = str.replace(/ > /g, '>');
  35. str = str.replace(/ < /g, '<');
  36. str = str.replace(/ >= /g, '>=');
  37. str = str.replace(/ <= /g, '<=');
  38. str = str.replace(/ \+= /g, '+=');
  39. str = str.replace(/ \-= /g, '-=');
  40. str = str.replace(/ \/= /g, '/=');
  41. str = str.replace(/ \*= /g, '*=');
  42. str = str.replace(/ = /g, '=');
  43. str = str.replace(/, /g, ',');
  44. str = str.replace(/\n\n/g, '\n');
  45. str = str.replace(/\n /g, '\n');
  46. for (var i = 0; i < str.length; i++) {
  47. currentChar = str[i];
  48. nextChar = str[i + 1];
  49. if (!insideComment && currentChar === '"') {
  50. var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\';
  51. if (!escaped) {
  52. insideString = !insideString;
  53. }
  54. }
  55. if (insideString) {
  56. continue;
  57. }
  58. if (!insideComment && currentChar + nextChar === '//') {
  59. ret += str.slice(offset, i);
  60. offset = i;
  61. insideComment = singleComment;
  62. i++;
  63. } else if (insideComment === singleComment && currentChar === '\n') {
  64. insideComment = 0;
  65. offset = i;
  66. } else if (!insideComment && currentChar + nextChar === '/*') {
  67. ret += str.slice(offset, i);
  68. offset = i;
  69. insideComment = multiComment;
  70. i++;
  71. continue;
  72. } else if (insideComment === multiComment && currentChar + nextChar === '*/') {
  73. i++;
  74. insideComment = 0;
  75. offset = i + 1;
  76. continue;
  77. }
  78. }
  79. return ret + (insideComment ? '' : str.substr(offset));
  80. }
  81. function processImports(loader, source, context, imports, cb) {
  82. if (imports.length === 0) {
  83. return cb(null, source);
  84. }
  85. var imp = imports.pop();
  86. loader.resolve(context, imp.key + '.fx', function (err, resolved) {
  87. if (err) {
  88. return cb(err);
  89. }
  90. loader.addDependency(resolved);
  91. fs.readFile(resolved, 'utf-8', function (err, src) {
  92. if (err) {
  93. return cb(err);
  94. }
  95. parse(loader, src, path.dirname(resolved), function (err, bld) {
  96. if (err) {
  97. return cb(err);
  98. }
  99. source = source.replace(imp.target, bld);
  100. processImports(loader, source, context, imports, cb);
  101. });
  102. });
  103. });
  104. }
  105. module.exports = parse;