Add regex awareness to jsonata formatter

This commit is contained in:
Nick O'Leary 2020-02-24 16:08:58 +00:00
parent e16fe1e6a5
commit 79feb691bd
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
1 changed files with 62 additions and 17 deletions

View File

@ -11,6 +11,7 @@
var length = str.length;
var start = 0;
var inString = false;
var inRegex = false;
var inBox = false;
var quoteChar;
var list = [];
@ -24,8 +25,13 @@
}
for (var i=0;i<length;i++) {
var c = str[i];
if (!inString) {
if (c === "'" || c === '"') {
if (!inString && !inRegex) {
if (c === "/") {
inRegex = true;
frame = {type:"regex",pos:i};
list.push(frame);
stack.push(frame);
} else if (c === "'" || c === '"') {
inString = true;
quoteChar = c;
frame = {type:"string",pos:i};
@ -37,6 +43,9 @@
} else if (c === ",") {
frame = {type:",",pos:i};
list.push(frame);
} else if (c === "&") {
frame = {type:"&",pos:i};
list.push(frame);
} else if (/[\(\[\{]/.test(c)) {
frame = {type:"open-block",char:c,pos:i};
list.push(frame);
@ -44,7 +53,8 @@
} else if (/[\}\)\]]/.test(c)) {
var oldFrame = stack.pop();
if (matchingBrackets[oldFrame.char] !== c) {
//console.log("Stack frame mismatch",c,"at",i,"expected",matchingBrackets[oldFrame.char],"from",oldFrame.pos);
// console.log("Stack frame mismatch",c,"at",i,"expected",matchingBrackets[oldFrame.char],"from",oldFrame.pos);
// console.log(list);
return str;
}
//console.log("Closing",c,"at",i,"compare",oldFrame.type,oldFrame.pos);
@ -53,19 +63,32 @@
list.push(frame);
}
} else {
if (c === quoteChar) {
// Next char must be a ]
inString = false;
stack.pop();
if (c === "\\") {
// an escaped char - stay in current mode and skip the next char
i++;
}
if (inString) {
if (c === quoteChar) {
// Next char must be a ]
inString = false;
var f = stack.pop();
f.end = i;
}
} else if (inRegex) {
if (c === "/") {
inRegex = false;
var f = stack.pop();
f.end = i;
}
}
}
}
// console.log("list",list);
// console.log(stack);
var result = str;
var indent = 0;
var offset = 0;
var pre,post,indented;
var pre,post,indented,hasNewline;
var longStack = [];
list.forEach(function(f) {
if (f.type === ";" || f.type === ",") {
@ -73,29 +96,51 @@
pre = result.substring(0,offset+f.pos+1);
post = result.substring(offset+f.pos+1);
indented = indentLine(post,indent);
result = pre+"\n"+indented;
offset += indented.length-post.length+1;
hasNewline = /\n$/.test(pre);
// console.log("A§"+pre+"§\n§"+indented+"§",hasNewline);
result = pre+(hasNewline?"":"\n")+indented;
offset += indented.length-post.length+(hasNewline?0:1);
}
} else if (f.type === "&") {
pre = result.substring(0,offset+f.pos+1);
var lastLineBreak = pre.lastIndexOf("\n");
var lineLength = pre.length - lastLineBreak;
if (lineLength > 70) {
post = result.substring(offset+f.pos+1);
if (!/^\n/.test(post)) {
indented = indentLine(post,indent);
hasNewline = /\n$/.test(pre);
result = pre+(hasNewline?"":"\n")+indented;
offset += indented.length-post.length+(hasNewline?0:1);
}
}
} else if (f.type === "open-block") {
if (f.width > 30) {
if (f.width > 40) {
longStack.push(true);
indent += 4;
pre = result.substring(0,offset+f.pos+1);
post = result.substring(offset+f.pos+1);
hasNewline = /\n$/.test(pre);
indented = indentLine(post,indent);
result = pre+(/\n$/.test(pre)?"":"\n")+indented;
offset += indented.length-post.length+1;
result = pre+(hasNewline?"":"\n")+indented;
offset += indented.length-post.length+(hasNewline?0:1);
} else {
longStack.push(false);
}
} else if (f.type === "close-block") {
if (f.width > 30) {
if (f.width > 40) {
indent -= 4;
pre = result.substring(0,offset+f.pos);
post = result.substring(offset+f.pos);
indented = indentLine(post,indent);
result = pre+(/\n$/.test(pre)?"":"\n")+indented;
offset += indented.length-post.length+1;
hasNewline = /\n *$/.test(pre);
if (hasNewline) {
result = pre + post;
} else {
result = pre+"\n"+indented;
offset += indented.length-post.length+1;
}
}
longStack.pop();
}