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)};
});