2016-11-28 10:42:58 +00:00
|
|
|
/* globals prettyPrintOne, vkbeautify */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Code operations.
|
|
|
|
*
|
|
|
|
* @author n1474335 [n1474335@gmail.com]
|
|
|
|
* @copyright Crown Copyright 2016
|
|
|
|
* @license Apache-2.0
|
|
|
|
*
|
|
|
|
* @namespace
|
|
|
|
*/
|
|
|
|
var Code = {
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* @constant
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
LANGUAGES: ["default-code", "default-markup", "bash", "bsh", "c", "cc", "coffee", "cpp", "cs", "csh", "cv", "cxx", "cyc", "htm", "html", "in.tag", "java", "javascript", "js", "json", "m", "mxml", "perl", "pl", "pm", "py", "python", "rb", "rc", "rs", "ruby", "rust", "sh", "uq.val", "xhtml", "xml", "xsl"],
|
|
|
|
/**
|
|
|
|
* @constant
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
LINE_NUMS: false,
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* Syntax highlighter operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {html}
|
|
|
|
*/
|
|
|
|
run_syntax_highlight: function(input, args) {
|
|
|
|
var language = args[0],
|
|
|
|
line_nums = args[1];
|
|
|
|
return "<code class='prettyprint'>" + prettyPrintOne(Utils.escape_html(input), language, line_nums) + "</code>";
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* @constant
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
BEAUTIFY_INDENT: "\\t",
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* XML Beautify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_xml_beautify: function(input, args) {
|
|
|
|
var indent_str = args[0];
|
|
|
|
return vkbeautify.xml(input, indent_str);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* JSON Beautify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_json_beautify: function(input, args) {
|
|
|
|
var indent_str = args[0];
|
2016-12-03 00:51:17 +00:00
|
|
|
if (!input) return "";
|
2016-11-28 10:42:58 +00:00
|
|
|
return vkbeautify.json(input, indent_str);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* CSS Beautify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_css_beautify: function(input, args) {
|
|
|
|
var indent_str = args[0];
|
|
|
|
return vkbeautify.css(input, indent_str);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* SQL Beautify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_sql_beautify: function(input, args) {
|
|
|
|
var indent_str = args[0];
|
|
|
|
return vkbeautify.sql(input, indent_str);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* @constant
|
|
|
|
* @default
|
|
|
|
*/
|
|
|
|
PRESERVE_COMMENTS: false,
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* XML Minify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_xml_minify: function(input, args) {
|
|
|
|
var preserve_comments = args[0];
|
|
|
|
return vkbeautify.xmlmin(input, preserve_comments);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* JSON Minify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_json_minify: function(input, args) {
|
2016-12-03 00:51:17 +00:00
|
|
|
if (!input) return "";
|
2016-11-28 10:42:58 +00:00
|
|
|
return vkbeautify.jsonmin(input);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* CSS Minify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_css_minify: function(input, args) {
|
|
|
|
var preserve_comments = args[0];
|
|
|
|
return vkbeautify.cssmin(input, preserve_comments);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* SQL Minify operation.
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_sql_minify: function(input, args) {
|
|
|
|
return vkbeautify.sqlmin(input);
|
|
|
|
},
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
/**
|
|
|
|
* Generic Code Beautify operation.
|
|
|
|
*
|
|
|
|
* Yeeeaaah...
|
|
|
|
*
|
|
|
|
* I'm not proud of this code, but seriously, try writing a generic lexer and parser that
|
|
|
|
* correctly generates an AST for multiple different languages. I have tried, and I can tell
|
|
|
|
* you it's pretty much impossible.
|
2016-12-14 16:39:17 +00:00
|
|
|
*
|
2016-11-28 10:42:58 +00:00
|
|
|
* This basically works. That'll have to be good enough. It's not meant to produce working code,
|
|
|
|
* just slightly more readable code.
|
2016-12-14 16:39:17 +00:00
|
|
|
*
|
2016-11-28 10:42:58 +00:00
|
|
|
* Things that don't work:
|
|
|
|
* - For loop formatting
|
|
|
|
* - Do-While loop formatting
|
|
|
|
* - Switch/Case indentation
|
|
|
|
* - Bit shift operators
|
|
|
|
*
|
|
|
|
* @author n1474335 [n1474335@gmail.com]
|
|
|
|
* @param {string} input
|
|
|
|
* @param {Object[]} args
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
run_generic_beautify: function(input, args) {
|
|
|
|
var code = input,
|
|
|
|
t = 0,
|
|
|
|
preserved_tokens = [],
|
|
|
|
m;
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove strings
|
|
|
|
var sstrings = /'([^'\\]|\\.)*'/g;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = sstrings.exec(code))) {
|
2016-11-28 10:42:58 +00:00
|
|
|
code = preserve_token(code, m, t++);
|
|
|
|
sstrings.lastIndex = m.index;
|
|
|
|
}
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
var dstrings = /"([^"\\]|\\.)*"/g;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = dstrings.exec(code))) {
|
2016-11-28 10:42:58 +00:00
|
|
|
code = preserve_token(code, m, t++);
|
|
|
|
dstrings.lastIndex = m.index;
|
|
|
|
}
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove comments
|
|
|
|
var scomments = /\/\/[^\n\r]*/g;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = scomments.exec(code))) {
|
2016-11-28 10:42:58 +00:00
|
|
|
code = preserve_token(code, m, t++);
|
|
|
|
scomments.lastIndex = m.index;
|
|
|
|
}
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
var mcomments = /\/\*[\s\S]*?\*\//gm;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = mcomments.exec(code))) {
|
2016-11-28 10:42:58 +00:00
|
|
|
code = preserve_token(code, m, t++);
|
|
|
|
mcomments.lastIndex = m.index;
|
|
|
|
}
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
var hcomments = /(^|\n)#[^\n\r#]+/g;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = hcomments.exec(code))) {
|
2016-11-28 10:42:58 +00:00
|
|
|
code = preserve_token(code, m, t++);
|
|
|
|
hcomments.lastIndex = m.index;
|
|
|
|
}
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove regexes
|
|
|
|
var regexes = /\/.*?[^\\]\/[gim]{0,3}/gi;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = regexes.exec(code))) {
|
2016-11-28 10:42:58 +00:00
|
|
|
code = preserve_token(code, m, t++);
|
|
|
|
regexes.lastIndex = m.index;
|
|
|
|
}
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Create newlines after ;
|
|
|
|
code = code.replace(/;/g, ";\n");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Create newlines after { and around }
|
|
|
|
code = code.replace(/{/g, "{\n");
|
|
|
|
code = code.replace(/}/g, "\n}\n");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove carriage returns
|
|
|
|
code = code.replace(/\r/g, "");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove all indentation
|
|
|
|
code = code.replace(/^\s+/g, "");
|
|
|
|
code = code.replace(/\n\s+/g, "\n");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove trailing spaces
|
|
|
|
code = code.replace(/\s*$/g, "");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove newlines before {
|
|
|
|
code = code.replace(/\n{/g, "{");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Indent
|
|
|
|
var i = 0,
|
|
|
|
level = 0;
|
|
|
|
while (i < code.length) {
|
|
|
|
switch(code[i]) {
|
|
|
|
case "{":
|
|
|
|
level++;
|
|
|
|
break;
|
|
|
|
case "\n":
|
|
|
|
if (i+1 >= code.length) break;
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
if (code[i+1] === "}") level--;
|
2016-11-28 10:42:58 +00:00
|
|
|
var indent = (level >= 0) ? Array(level*4+1).join(" ") : "";
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
code = code.substring(0, i+1) + indent + code.substring(i+1);
|
|
|
|
if (level > 0) i += level*4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add strategic spaces
|
|
|
|
code = code.replace(/\s*([!<>=+-/*]?)=\s*/g, " $1= ");
|
|
|
|
code = code.replace(/\s*<([=]?)\s*/g, " <$1 ");
|
|
|
|
code = code.replace(/\s*>([=]?)\s*/g, " >$1 ");
|
|
|
|
code = code.replace(/([^+])\+([^+=])/g, "$1 + $2");
|
|
|
|
code = code.replace(/([^-])-([^-=])/g, "$1 - $2");
|
|
|
|
code = code.replace(/([^*])\*([^*=])/g, "$1 * $2");
|
|
|
|
code = code.replace(/([^/])\/([^/=])/g, "$1 / $2");
|
|
|
|
code = code.replace(/\s*,\s*/g, ", ");
|
|
|
|
code = code.replace(/\s*{/g, " {");
|
|
|
|
code = code.replace(/}\n/g, "}\n\n");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Just... don't look at this
|
|
|
|
code = code.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)\s*\n([^{])/gim, "$1 ($2)\n $3");
|
|
|
|
code = code.replace(/(if|for|while|with|elif|elseif)\s*\(([^\n]*)\)([^{])/gim, "$1 ($2) $3");
|
|
|
|
code = code.replace(/else\s*\n([^{])/gim, "else\n $1");
|
|
|
|
code = code.replace(/else\s+([^{])/gim, "else $1");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Remove strategic spaces
|
|
|
|
code = code.replace(/\s+;/g, ";");
|
|
|
|
code = code.replace(/\{\s+\}/g, "{}");
|
|
|
|
code = code.replace(/\[\s+\]/g, "[]");
|
|
|
|
code = code.replace(/}\s*(else|catch|except|finally|elif|elseif|else if)/gi, "} $1");
|
2016-12-14 16:39:17 +00:00
|
|
|
|
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
// Replace preserved tokens
|
|
|
|
var ptokens = /###preserved_token(\d+)###/g;
|
2016-12-14 16:39:17 +00:00
|
|
|
while ((m = ptokens.exec(code))) {
|
|
|
|
var ti = parseInt(m[1], 10);
|
2016-11-28 10:42:58 +00:00
|
|
|
code = code.substring(0, m.index) + preserved_tokens[ti] + code.substring(m.index + m[0].length);
|
|
|
|
ptokens.lastIndex = m.index;
|
|
|
|
}
|
|
|
|
|
|
|
|
return code;
|
2016-12-14 16:39:17 +00:00
|
|
|
|
2016-11-28 10:42:58 +00:00
|
|
|
function preserve_token(str, match, t) {
|
|
|
|
preserved_tokens[t] = match[0];
|
|
|
|
return str.substring(0, match.index) +
|
|
|
|
"###preserved_token" + t + "###" +
|
|
|
|
str.substring(match.index + match[0].length);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|