UNPKG

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