Blame view

node_modules/reduce-function-call/index.js 1.91 KB
2a09d1a4   liuqimichale   添加宜春 天水 宣化
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
  /*
   * Module dependencies
   */
  var balanced = require("balanced-match")
  
  /**
   * Expose `reduceFunctionCall`
   *
   * @type {Function}
   */
  module.exports = reduceFunctionCall
  
  /**
   * Walkthrough all expressions, evaluate them and insert them into the declaration
   *
   * @param {Array} expressions
   * @param {Object} declaration
   */
  
  function reduceFunctionCall(string, functionRE, callback) {
    var call = string
    return getFunctionCalls(string, functionRE).reduce(function(string, obj) {
      return string.replace(obj.functionIdentifier + "(" + obj.matches.body + ")", evalFunctionCall(obj.matches.body, obj.functionIdentifier, callback, call, functionRE))
    }, string)
  }
  
  /**
   * Parses expressions in a value
   *
   * @param {String} value
   * @returns {Array}
   * @api private
   */
  
  function getFunctionCalls(call, functionRE) {
    var expressions = []
  
    var fnRE = typeof functionRE === "string" ? new RegExp("\\b(" + functionRE + ")\\(") : functionRE
    do {
      var searchMatch = fnRE.exec(call)
      if (!searchMatch) {
        return expressions
      }
      if (searchMatch[1] === undefined) {
        throw new Error("Missing the first couple of parenthesis to get the function identifier in " + functionRE)
      }
      var fn = searchMatch[1]
      var startIndex = searchMatch.index
      var matches = balanced("(", ")", call.substring(startIndex))
  
      if (!matches || matches.start !== searchMatch[0].length - 1) {
        throw new SyntaxError(fn + "(): missing closing ')' in the value '" + call + "'")
      }
  
      expressions.push({matches: matches, functionIdentifier: fn})
      call = matches.post
    }
    while (fnRE.test(call))
  
    return expressions
  }
  
  /**
   * Evaluates an expression
   *
   * @param {String} expression
   * @returns {String}
   * @api private
   */
  
  function evalFunctionCall (string, functionIdentifier, callback, call, functionRE) {
    // allow recursivity
    return callback(reduceFunctionCall(string, functionRE, callback), functionIdentifier, call)
  }