Code coverage report for src/parse.js

Statements: 100% (41 / 41)      Branches: 96.55% (28 / 29)      Functions: 100% (3 / 3)      Lines: 100% (40 / 40)      Ignored: none     

All files » src/ » parse.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90  1 1 1   1               1               1 175 174         174 563 563 223 223 26         174   174     1   225 225 225 225   225   777   563 563   563     563 1 1 1     563   461   102   51       51 51 51 51           174     1  
'use strict';
var Parser  = require('./parse/index');
var _parse = Parser.parse;
var utils = require('./utils');
 
var blockTypes = {
  if: true,
  foreach: true,
  macro: true,
  noescape: true,
  define: true
};
 
var customBlocks = [];
 
/**
 * @param {string} str string to parse
 * @param {object} blocks self define blocks, such as `#cms(1) hello #end`
 * @param {boolean} ignoreSpace if set true, then ignore the newline trim.
 * @return {array} ast array
 */
var parse = function(str, blocks, ignoreSpace) {
  var asts = _parse(str);
  customBlocks = blocks || {};
 
  /**
   * remove all newline after all direction such as `#set, #each`
   */
  ignoreSpace || utils.forEach(asts, function trim(ast, i) {
    var TRIM_REG = /^[ \t]*\n/;
    if (ast.type && ast.type !== 'references') {
      var _ast = asts[i + 1];
      if (typeof _ast === 'string' && TRIM_REG.test(_ast)) {
        asts[i + 1] = _ast.replace(TRIM_REG, '');
      }
    }
  });
 
  var ret = makeLevel(asts);
 
  return utils.isArray(ret) ? ret : ret.arr;
};
 
function makeLevel(block, index) {
 
  var len = block.length;
  index = index || 0;
  var ret = [];
  var ignore = index - 1;
 
  for (var i = index; i < len; i++) {
 
    if (i <= ignore) continue;
 
    var ast = block[i];
    var type = ast.type;
 
    var isBlockType = blockTypes[type];
 
    // 自定义类型支持
    if (!isBlockType && ast.type === 'macro_call' && customBlocks[ast.id]) {
      isBlockType = true;
      ast.type = ast.id;
      delete ast.id;
    }
 
    if (!isBlockType && type !== 'end') {
 
      ret.push(ast);
 
    } else if (type === 'end') {
 
      return {arr: ret, step: i};
 
    } else {
 
      var _ret = makeLevel(block, i + 1);
      ignore = _ret.step;
      _ret.arr.unshift(block[i]);
      ret.push(_ret.arr);
 
    }
 
  }
 
  return ret;
}
 
module.exports = parse;