code: function parseTextBlock(source, open, close, greedy, onInBlock, onOutBlock) {
          var closeLen = close.length;
          var texts = source.split(open);
          var level = 0;
          var buf = [];
  
          for (var i = 0, len = texts.length; i < len; i++) {
              var text = texts[i];
  
              if (i) {
                  var openBegin = 1;
                  level++;
                  /* eslint-disable no-constant-condition */
                  while (1) {
                      var closeIndex = text.indexOf(close);
                      if (closeIndex < 0) {
                          buf.push(level > 1 && openBegin ? open : '', text);
                          break;
                      }
  
                      level = greedy ? level - 1 : 0;
                      buf.push(
                          level > 0 && openBegin ? open : '',
                          text.slice(0, closeIndex),
                          level > 0 ? close : ''
                      );
                      text = text.slice(closeIndex + closeLen);
                      openBegin = 0;
  
                      if (level === 0) {
                          break;
                      }
                  }
                  /* eslint-enable no-constant-condition */
  
                  if (level === 0) {
                      onInBlock(buf.join(''));
                      onOutBlock(text);
                      buf = [];
                  }
              }
              else {
                  text && onOutBlock(text);
              }
          }
  
          if (level > 0 && buf.length > 0) {
              onOutBlock(open);
              onOutBlock(buf.join(''));
          }
      }
docs: 解析文本片段中以固定字符串开头和结尾的包含块
  用于 命令串：<!-- ... --> 和 变量替换串：${...} 的解析
  
  @inner
  @param {string} source 要解析的文本
  @param {string} open 包含块开头
  @param {string} close 包含块结束
  @param {boolean} greedy 是否贪婪匹配
  @param {function({string})} onInBlock 包含块内文本的处理函数
  @param {function({string})} onOutBlock 非包含块内文本的处理函数