Share Pascal code folding

CodeMirror.registerHelper("fold", "pascal", function(cm, start) {
  var line = start.line, lineText = cm.getLine(line);
  var tokenType;
  function findOpening(kenType,openCh) {
    for (var at = start.ch, pass = 0;;) {
      var found = at <= 0 ? -1 : lineText.toUpperCase().lastIndexOf(openCh.toUpperCase(), at - 1);
      if (found == -1) {
        if (pass == 1) break;
        pass = 1;
        at = lineText.length;
        continue;
      }
	  
      if (pass == 1 && found < start.ch) break;
      tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
	  
	  if (tokenType == kenType) return found + 1;
      at = found - 1;
    }
  };
  var startToken = "function", endToken = "end", findtype = "keyword",startCh = findOpening(findtype,startToken);
  if (startCh == null) {
      startToken = "procedure";
      startCh = findOpening(findtype,startToken);
	  if (startCh == null) {
		  startToken = "object";
          startCh = findOpening(findtype,startToken);
		  if (startCh == null) {
			  startToken = "{";
			  endToken   = "}";
			  findtype   = "comment"
			  startCh = findOpening(findtype,startToken);
			  if (startCh == null) {
				  startToken = "(*";
				  endToken   = "*)";
				  findtype   = "comment"
				  startCh = findOpening(findtype,startToken);
				  if (startCh == null) {
					  startToken = "[";
					  endToken   = "]";
					  findtype   = null;
					  startCh = findOpening(findtype,startToken);
					  if (startCh == null) {
						  startToken = "(";
						  endToken   = ")";
						  findtype   = null;
						  startCh = findOpening(findtype,startToken);
					  }
				  }
			  }
		  }
	  }	  
  }
  
  if (startCh == null) return;
  
  function findNextOpen(kenType,nextText,currentLine,curPos){
	var vText = cm.getLine(currentLine);
	var vNextOpen = vText.toUpperCase().indexOf(nextText.toUpperCase(), curPos);
	if (vNextOpen >= 0){
	var vtokenType = cm.getTokenAt(CodeMirror.Pos(currentLine, vNextOpen + 1));
	if (vtokenType.type == kenType) return vNextOpen;
	} else{
	return -1;
	}
	return -1;
  }
  
  var keyCount = 1;//节点数
  var oldCount = 0;//旧节点
  var vieCount = 0;//代码块
  var poiCount = 0;//尖括号数
  
  var count = 1, lastLine = cm.lastLine(), end, endCh;
  outer: for (var i = line; i <= lastLine; ++i) {
    var text = cm.getLine(i), pos = i == line ? startCh : 0;

    for (;;) {
      var nextOpen = -1;

	  nextOpen = findNextOpen(findtype,"function",i,pos);
	  if (nextOpen < 0) nextOpen = findNextOpen(findtype,"procedure",i,pos);
      if (nextOpen >= 0){ 
	      keyCount = keyCount + 1; 
	  } 
	  
	  if (nextOpen < 0) nextOpen = findNextOpen(findtype,"object",i,pos);
	  
	  if (nextOpen < 0){ 
	      nextOpen = findNextOpen(findtype,"begin",i,pos);
	      if (nextOpen >= 0){
			vieCount = vieCount + 1;
			if(keyCount != oldCount){
			  oldCount = keyCount;
	          nextOpen = -1
			};
		  }
	  };
	  
	  if (nextOpen < 0){ 
		  nextOpen = findNextOpen(findtype, "try",i,pos);
		  if (nextOpen >= 0) vieCount = vieCount + 1; 
	  };  
	  
	  if (nextOpen < 0){ 
		  nextOpen = findNextOpen(findtype, "case",i,pos);
		  if (nextOpen >= 0) vieCount = vieCount + 1;
	  };
	  
	  var poiOpen = -1;
	  poiOpen = findNextOpen("operator", "<",i,pos);
	  if (poiOpen >= 0) poiCount = poiCount + 1;
	  
	  var nextClose = findNextOpen(findtype, endToken,i,pos);
	  if (nextClose >= 0){
		  if (poiCount > 0){
			  nextClose = -1;
	      }else{
			  vieCount = vieCount - 1;
			  if (vieCount == 0){
				  keyCount = keyCount - 1;
				  //如果记录数等于1的时候,旧记录数要重置0
				  if (keyCount = 1) oldCount = 0;
				  };
		  }
	  };
	  
	  var poiClose = -1;
	  poiClose = findNextOpen("operator", ">",i,pos);
	  if (poiClose >= 0) poiCount = poiCount - 1;
	  
      if (nextOpen < 0) nextOpen = text.length;
      if (nextClose < 0) nextClose = text.length;
      pos = Math.min(nextOpen, nextClose);
      if (pos == text.length) break;
      if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
        if (pos == nextOpen) ++count;
        else 
		if (!--count) { end = i; endCh = pos; break outer; }
      }
      ++pos;
    }
  }
  if (end == null || line == end /*&& endCh == startCh*/) return;

  return {from: CodeMirror.Pos(line, lineText.length),
          to: CodeMirror.Pos(end, endCh)};
});