UNPKG

liberty-prettydiff

Version:

Language aware code comparison tool for several web based languages. It also beautifies, minifies, and a few other things.

1,052 lines (1,049 loc) 87.5 kB
/*global __dirname, ace, define, global, module, process, require, WScript*/ /*jslint for: true, this: true*/ /* How to define a new option: 1. definitions - define the option 2. validate - logic to assign values against accepted criteria 3. pdcomment - only necessary if option is string type with a list of accepted values 4. domops - associate ID names (from HTML) to values for populating the pretty diff comment in the web tool Functions map: * definitions - a big object defining all the options * default - pulls default values out of the definitions object. This is necessary to prevent collisions when processing multiple files simultanesouly * versionString - a function to build out human readable messaging about the current version from data in prettydiff.js * consolePrint - a handy function to print documentation on all options and usage data to the console in the browser or command line. ** to execute in the browser console: global.prettydiff.options.functions.consolePrint() ** or use the alias document.consolePrint() from api/dom.js * pdcomment - processes option overrides from the prettydiff.com code comment * validate - process user input against supported options and their acceptable values. I have plans to merge this into the definitions object * domops - updates the comment string that appears in the options area of the web tool * node - parses node arguments into options for submission to the validate function * binary - a handy dandy tool to remove control characters from text output */ (function options_init() { "use strict"; var options = {}; global.prettydiff.options = { functions: {} }; options = global.prettydiff.options; if (typeof require === "function" && (typeof ace !== "object" || ace.prettydiffid === undefined)) { (function glib_options() { var localPath = (typeof process === "object" && typeof process.cwd === "function" && (process.cwd() === "/" || (/^([a-z]:\\)$/).test(process.cwd()) === true) && typeof __dirname === "string") ? __dirname : "."; if (global.prettydiff.language === undefined) { global.prettydiff.language = require(localPath + "/lib/language.js"); } }()); } options.functions.definitions = { apacheVelocity: { type: "boolean", definition: "Provides support for Apache Velocity template language.", default: false }, api : { type: "string", definition: "An enternal option to help identify environment specific needs.", default: false }, attributetoken: { type: "boolean", definition: "Provides markups attributes as separate tokens in the parse table of mode parse, otherwise attributes are a data property of their respective element.", default: false }, brace_style: { type: "string", definition: "Emulates JSBeautify's brace_style option using existing Pretty Diff options.", values: ["collapse", "collapse-preserve-inline", "expand", "none"], default: "none" }, braceline: { type: "boolean", definition: "If true a new line character will be inserted after opening curly braces and before closing curly braces.", default: false }, bracepadding: { type: "boolean", definition: "Inserts a space after the start of a contain and before the end of the container in JavaScript if the contents of that container are not indented; such as: conditions, function arguments, and escaped sequences of template strings.", default: false }, braces: { type: "string", definition: "If lang is 'javascript' and mode is 'beautify' this determines if opening curly braces will exist on the same line as their condition or be forced onto a new line.", values: ["knr", "allman"], default: "knr" }, color: { type: "string", definition: "The color scheme of the reports.", default: "white", values: ["canvas", "shadow", "white"] }, comments: { type: "string", definition: "If mode is 'beautify' this will determine whether comments should always start at position 0 of each line or if comments should be indented according to the code.", default: "indent", values: ["indent", "noindent"] }, commline: { type: "boolean", definition: "If a blank new line should be forced above comments in markup.", default: false }, compressedcss: { type: "boolean", definition: "If CSS should be beautified in a style where the properties and values are minifed for faster reading of selectors.", default: false }, conditional: { type: "boolean", definition: "If true then conditional comments used by Internet Explorer are preserved at minification of markup.", default: false }, content: { type: "boolean", definition: "If true and mode is 'diff' this will normalize all string literals in JavaScript to 'text' and all content in markup to 'text' so as to eliminate some differences from the HTML diff report.", default: false }, context: { type: "number", definition: "This shortens the diff output by allowing a specified number of equivalent lines between each line of difference.", default: -1 }, correct: { type: "boolean", definition: "Automatically correct some sloppiness in JavaScript and markup.", default: false }, crlf: { type: "boolean", definition: "If line termination should be Windows (CRLF) format. Unix (LF) format is the default.", default: false }, cssinsertlines: { type: "boolean", definition: "Inserts new line characters between every CSS code block.", default: false }, csvchar: { type: "string", definition: "The character to be used as a separator if lang is 'csv'. Any string combination is accepted.", default: "," }, diff: { type: "string", definition: "The code sample to be compared to 'source' option. This is required if mode is 'diff'.", default: "" }, diffcli: { type: "boolean", definition: "If true only text lines of the code differences are returned instead of an HTML diff report.", default: false }, diffcomments: { type: "boolean", definition: "If true then comments will be preserved so that both code and comments are compared by the diff engine.", default: false }, difflabel: { type: "string", definition: "This allows for a descriptive label for the diff file code of the diff HTML output.", default: "New Sample" }, diffspaceignore: { type: "boolean", definition: "If white space only differences should be ignored by the diff tool.", default: false }, diffview: { type: "string", definition: "This determines whether the diff HTML output should display as a side-by-side comparison or if the differences should display in a single table column.", values: ["inline", "sidebyside"], default: "sidebyside" }, dustjs: { type: "boolean", definition: "If the provided markup code is a Dust.js template.", default: false }, elseline: { type: "boolean", definition: "If elseline is true then the keyword 'else' is forced onto a new line in JavaScript beautification.", default: false }, endcomma: { type: "string", definition: "If there should be a trailing comma in JavaScript arrays and objects. Value \"multiline\" only applies to modes beautify and diff.", values: ["always", "multiline", "never"], default: "never" }, endquietly: { type: "string", definition: "A node only option to determine if terminal logging should be allowed or suppressed.", values: ["", "log", "quiet"], default: "" }, force_attribute: { type: "boolean", definition: "If all markup attributes should be indented each onto their own line.", default: false }, force_indent: { type: "boolean", definition: "If lang is 'markup' this will force indentation upon all content and tags without regard for the creation of new text nodes.", default: false }, formatArray: { type: "string", definition: "Determines if all JavaScript array indexes should be indented, never indented, or left to the default.", values: ["default", "indent", "inline"], default: "default" }, formatObject: { type: "string", definition: "Determines if all JavaScript array indexes should be indented, never indented, or left to the default.", values: ["default", "indent", "inline"], default: "default" }, functionname: { type: "boolean", definition: "If a space should follow a JavaScript function name.", default: false }, help: { type: "number", definition: "A node only option to print documentation to the console. The value determines where to wrap text.", default: 80 }, html: { type:"boolean", definition: "If lang is 'markup' this will provide extra support for HTML specific sloppiness.", default: false }, inchar: { type:"string", definition: "The string characters to comprise a single indentation. Any string combination is accepted.", default: " " }, inlevel: { type:"number", definition: "How much indentation padding should be applied to JavaScript beautification?", default: 0 }, insize: { type: "number", definition: "The number of characters to comprise a single indentation.", default: 4 }, jekyll: { type: "boolean", definition: "If YAML Jekyll HTML template comments are supported.", default: false }, jsscope: { type: "string", definition: "An educational tool to generate HTML output of JavaScript code to identify scope regions and declared references by color.", values: { none: "prevents use of this option", report: "generates HTML output that renders in web browsers", html: "generates HTML output with escaped angle braces and ampersands for embedding as code, which is handy in code producing tools" }, default: "none" }, jsx: { type: "boolean", definition: "An internal flag used to identify if a given code sample is React JSX code.", default: false }, lang: { type:"string", definition: "The programming language of the source file.", values: ["auto", "markup", "javascript", "css", "html", "csv", "text"], default: "auto" }, langdefault: { type: "string", definition: "The fallback option if option 'lang' is set to 'auto' and a language cannot be detected.", values: ["markup", "javascript", "css", "html", "csv", "text"], default: "text" }, listoptions: { type: "boolean", definition: "A Node.js only option that writes current option settings to the console.", default: false }, methodchain: { type: "string", definition: "Whether consecutive JavaScript methods should be chained onto a single line of code instead of indented.", values: ["chain", "indent", "none"], default: "indent" }, miniwrap: { type: "boolean", definition: "Whether minified JavaScript should wrap after a specified character width. This option requires a value from option 'wrap'.", default: false }, mode: { type: "string", definition: "The operation to be performed.", values: { analysis: "returns a code examination report", beautify: "beautifies code and returns a string", diff: "returns either command line list of differences or an HTML report", minify: "minifies code and returns a string", parse: "using option 'parseFormat' returns an object with shallow arrays, a multidimensional array, or an HTML report" }, default: "diff" }, neverflatten: { type: "boolean", definition: "If destructured lists in JavaScript should never be flattend.", default: false }, nocaseindent: { type: "boolean", definition: "If a case statement should receive the same indentation as the containing switch block.", default: false }, nochainindent: { type: "boolean", definition: "If indentation should be prevent of JavaScript method chains broken onto multiple lines.", default: false }, nodeasync: { type: "boolean", definition: "An internal option manage processing of multiple files simultanously", default: false }, nodeerror: { type: "boolean", definition: "A Node.js only option if parse errors should be written to the console.", default: false }, noleadzero: { type: "boolean", definition: "Whether leading 0s in CSS values immediately preceeding a decimal should be removed or prevented.", default: false }, objsort: { type: "string", definition: "Sorts markup attributes and properties by key name in JavaScript and CSS.", values: ["all", "css", "js", "markup", "none"], default: "none" }, output: { type: "string", definition: "The path of the directory, if readmethod is value 'directory', or path and name of the file to write the output. The path will be created or overwritten.", default: "" }, parseFormat: { type: "string", definition: "Determines the output format for 'parse' mode.", values: { htmltable: "generates a human readable report in the format of an HTML table", parallel: "returns a series of parallel arrays", sequential: "returns an array where each index is a child array containing the parsed token and all descriptive data" }, default: "parallel" }, parseSpace: { type: "boolean", definition: "Whether whitespace tokens should be included.", default: false }, preserve: { type: "number", definition: "The maximum number of empty lines to retain.", default: 0 }, qml: { type: "boolean", definition: "Enables QML syntax support in the jspretty library.", default: false }, quote: { type: "boolean", definition: "If true and mode is 'diff' then all single quote characters will be replaced by double quote characters in both the source and diff file input so as to eliminate some differences from the diff report HTML output.", default: false }, quoteConvert: { type: "string", definition: "If the quotes of JavaScript strings or markup attributes should be converted to single quotes or double quotes.", values: ["double", "single", "none"], default: "none" }, readmethod: { type: "string", definition: "The readmethod determines how Node.js should receive input and output.", values: { auto: "changes to value subdirectory, file, or screen depending on source resolution", screen: "reads from screen and outputs to screen", file: "reads a file and outputs to a file. file requires option 'output'", filescreen: "reads a file and writes to screen", directory: "process all files in the specified directory only", subdirectory: "process all files in a directory and its subdirectories" }, default: "auto" }, selectorlist: { type: "boolean", definition: "If comma separated CSS selectors should be retained on a single line of code.", default: false }, semicolon: { type: "boolean", definition: "If true and mode is 'diff' and lang is 'javascript' all semicolon characters that immediately preceed any white space containing a new line character will be removed so as to elimate some differences from the code comparison.", default: false }, source: { type: "string", definition: "The source code or location for interpretation. This option is required for all modes.", default: "" }, sourcelabel: { type: "string", definition: "This allows for a descriptive label of the source file code of the diff HTML output.", default: "Source Sample" }, space: { type: "boolean", definition: "Inserts a space following the function keyword for anonymous functions.", default: true }, spaceclose: { type: "boolean", definition: "Markup self-closing tags end will end with ' />' instead of '/>'.", default: false }, style: { type: "string", definition: "If mode is 'beautify' and lang is 'markup' or 'html' this will determine whether the contents of script and style tags should always start at position 0 of each line or if such content should be indented starting from the opening script or style tag.", values: ["indent", "noindent"], default: "indent" }, styleguide: { type: "string", definition: "Provides a collection of option presets to easily conform to popular JavaScript style guides.", values: ["airbnb", "crockford", "google", "grunt", "jquery", "jslint", "mediawiki", "meteor", "yandex", "none"], default: "none" }, summaryonly: { type: "boolean", definition: "Node only option to output only number of differences.", default: false }, tagmerge: { type: "boolean", definition: "Allows immediately adjacement start and end markup tags of the same name to be combined into a single self-closing tag.", default: false }, tagsort: { type: "boolean", definition: "Sort child items of each respective markup parent element.", default: false }, textpreserve: { type: "boolean", definition: "If text in the provided markup code should be preserved exactly as provided. This option eliminates beautification and wrapping of text content.", default: false }, ternaryline: { type: "boolean", definition: "If ternary operators in JavaScript (? and :) should remain on the same line.", default: false }, titanium: { type: "boolean", definition: "Forces the JavaScript parser to parse Titanium Style Sheets instead of JavaScript.", default: false }, topcoms: { type: "boolean", definition: "If mode is 'minify' this determines whether comments above the first line of code should be kept.", default: false }, twig: { type: "boolean", definition: "If markuppretty is passing twig tag data to jspretty.", default: false }, typescript: { type: "boolean", definition: "Identifies certain edge cases where TypeScript is in conflict with React JSX regarding type generics", default: false }, unformatted: { type: "boolean", definition: "If markup tags should have their insides preserved.", default: false }, varword: { type: "string", definition: "If consecutive JavaScript variables should be merged into a comma separated list or if variables in a list should be separated.", values: ["each", "list", "none"], default: "none" }, version: { type: "boolean", definition: "A Node.js only option to write the version information to the console.", default: false }, vertical: { type: "string", definition: "If lists of assignments and properties should be vertically aligned.", values: ["all", "css", "js", "none"], default: "none" }, wrap: { type: "number", definition: "How many characters long text content in markup or strings in JavaScript can be before wrapping. A value of 0 turns this feature off. A value of -1 will concatenate strings in JavaScript if separated by a '+' operator.", default: 0 } }; options.functions.default = function options_default() { var keys = Object.keys(options.functions.definitions), populate = function options_default_populate(name) { if (name !== "api" && name !== "diff" && name !== "output" && name !== "source" && name !== "nodeasync" && (options.functions.nodeArgs === undefined || options.functions.nodeArgs[name] === undefined)) { options[name] = options.functions.definitions[name].default; } }; keys.forEach(populate); }; options.functions.versionString = function options__versionString() { var dstring = "", mstring = 0, month = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; if (global.prettydiff.edition === undefined) { return ""; } dstring = global .prettydiff .edition .latest .toString(); mstring = Number(dstring.slice(2, 4)) - 1; return "\u001B[36mVersion\u001B[39m: " + global.prettydiff.edition.version + " \u001B[36mDated\u001B[39m: " + dstring.slice(4, 6) + " " + month[mstring] + " 20" + dstring.slice(0, 2); }; options.functions.consolePrint = function options_consolePrint() { var list = Object.keys(options.functions.definitions), a = 0, b = 0, longest = 0, len = list.length, def = "", name = "", type = "", vlist = [], names = [], vals = [], lf = (options.crlf === true) ? "\r\n" : "\n", limit = (options.help === undefined) ? 78 : options.help - 2, namecolor = function options_colorPrint_namecolor(item) { return " * \"\u001B[32m" + item.replace(" * \"", "") + "\u001B[39m"; }, vertical = function options_consolePrint_vertical(items) { var mostest = 0, x = 0, y = 0, leng = items.length, newitems = []; for (x = 0; x < leng; x += 1) { if (items[x].length > mostest) { mostest = items[x].length; } } for (x = 0; x < leng; x += 1) { y = items[x].length; newitems.push(items[x]); if (y < mostest) { do { y += 1; newitems[x] = newitems[x] + " "; } while (y < mostest); } } return [newitems, mostest]; }, wrap = function options_consolePrint_wrap(values) { var start = true, wrapper = [], wrappit = function options_consolePrint_wrap_wrappit() { var indent = (values === true && start === false) ? " " : " ", c = limit - indent.length; name = name.replace(/^(\s+)/, ""); if (name.length < c) { wrapper.push(indent + name); name = ""; return; } if (name.charAt(c) !== " " || name.charAt(c - 1) === " ") { do { c -= 1; } while (c > 0 && (name.charAt(c) !== " " || name.charAt(c - 1) === " ")); } if (c === 0) { wrapper.push(indent + name); name = ""; return; } wrapper.push(indent + name.slice(0, c)); name = name.slice(c); }; do { wrappit(); start = false; } while (name.length > 0); if (options.crlf === true) { return wrapper.join("\r\n"); } return wrapper.join("\n"); }, output = ["", "\u001B[1mOptions\u001B[22m"]; names = vertical(list); longest = names[1]; names = names[0]; name = " Name"; b = name.length; if (b < longest) { do { b += 1; name = name + " "; } while (b < longest); } name = name + " - Type - Default"; output.push(""); output.push(name); b = 0; name = ""; do { b += 1; name = name + "-"; } while (b < limit + 2); output.push(name); for (a = 0; a < len; a += 1) { name = "* \u001B[32m" + names[a] + "\u001B[39m"; type = options.functions.definitions[list[a]].type; if (type === "string") { type = "\u001B[33m" + type + "\u001B[39m "; def = options.functions.definitions[list[a]].default; if (def === " ") { def = "(space)"; } else if (def === "") { def = "(empty string)"; } else { def = "\"" + def + "\""; } } else if (type === "number") { type = "\u001B[36m" + type + "\u001B[39m "; def = options.functions.definitions[list[a]].default.toString(); } else { type = "\u001B[35m" + type + "\u001B[39m"; def = options.functions.definitions[list[a]].default.toString(); } name = name + " - " + type + " - " + def; output.push(name); name = options.functions.definitions[list[a]].definition; if (name.length < limit) { output.push(" " + name); } else { output.push(wrap(false)); } vlist = options.functions.definitions[list[a]].values; if (vlist !== undefined) { if (typeof vlist.length === "number") { name = "Accepted values: \"" + vlist.toString().replace(/,/g, "\", \"") + "\""; name = "\u001B[31m" + wrap(false); name = name.replace("Accepted values: \"", "Accepted values:\u001B[39m \"\u001B[32m"); name = name.replace(/,\u0020"/g, ", \"\u001B[32m"); name = name.replace(/",/g, "\u001B[39m\","); output.push(name); } else { output.push(" \u001B[31mAccepted values:\u001B[39m"); vlist = Object.keys(options.functions.definitions[list[a]].values); vals = vertical(vlist)[0]; b = 0; do { vals[b] = vals[b] + " "; name = " * \"" + vals[b].replace(" ", "\"") + " - " + options.functions.definitions[list[a]].values[vlist[b]]; name = wrap(true); name = name.replace(/\u0020\u0020\*\u0020"\w+/, namecolor); output.push(name); b += 1; } while (b < vlist.length); } } output.push(""); } if (options.api === "node") { output.push("\u001B[1mUsage\u001B[22m"); output.push("\u001B[35mnode api/node-local.js\u001B[39m \u001B[32moption1:\u001B[39m\u001B[33m\"value\"\u001B[39m \u001B[32moption2:\u001B[39m\u001B[33m\"value\"\u001B[39m ..."); output.push("\u001B[35mnode api/node-local.js\u001B[39m \u001B[32msource:\u001B[39m\u001B[33m\"myApplication.js\"\u001B[39m \u001B[32mreadmethod:\u001B[39m\u001B[33m\"filescreen\"\u001B[39m \u001B[32mmode:\u001B[39m\u001B[33m\"beautify\"\u001B[39m"); output.push("\u001B[35mnode api/node-local.js\u001B[39m \u001B[32msource:\u001B[39m\u001B[33m\"old_directory\"\u001B[39m \u001B[32mdiff:\u001B[39m\u001B[33m\"new_directory\"\u001B[39m \u001B[32mreadmethod:\u001B[39m\u001B[33m\"subdirectory\"\u001B[39m"); output.push("\u001B[35mnode api/node-local.js\u001B[39m \u001B[32mhelp\u001B[39m:80 to see this help message, the number value sets word wrap"); output.push("\u001B[35mnode api/node-local.js\u001B[39m \u001B[32mversion\u001B[39m to see only the version line"); output.push("\u001B[35mnode api/node-local.js\u001B[39m \u001B[32mlist\u001B[39m to see the current settings"); output.push(""); output.push(options.functions.versionString()); output.push(""); return output.join(lf); } output.push(""); output.push(options.functions.versionString()); output.push(""); return output.join(lf).replace(/\u001b\[\d+m/g, ""); }; options.functions.pdcomment = function options_pdcomment() { var comment = options.source, a = 0, b = options.source.length, str = "/*prettydiff.com", c = options .source .indexOf(str) + 16, build = [], comma = -1, g = 0, sourceChar = [], quote = "", sind = options .source .indexOf(str), dind = options .diff .indexOf(str); if (sind < 0) { str = "<!--prettydiff.com"; sind = options .source .indexOf(str); c = sind + 18; } if (dind < 0) { dind = options .source .indexOf("<!--prettydiff.com"); } if ((options.source.charAt(c - 17) === "\"" && options.source.charAt(c) === "\"") || (sind < 0 && dind < 0)) { return; } if (sind > -1 && (/^(\s*\{\s*"token"\s*:\s*\[)/).test(options.source) === true && (/\],\s*"types"\s*:\s*\[/).test(options.source) === true) { return; } if (sind < 0 && dind > -1 && (/^(\s*\{\s*"token"\s*:\s*\[)/).test(options.diff) === true && (/\],\s*"types"\s*:\s*\[/).test(options.diff) === true) { return; } if (c === 15 && typeof options.diff === "string") { c = options .diff .indexOf("/*prettydiff.com") + 16; comment = options.diff; } else if (c === 17 && typeof options.diff === "string") { str = "<!--prettydiff.com"; c = options .diff .indexOf(str) + 18; comment = options.diff; } else if (c === 17) { return; } for (c = c; c < b; c += 1) { if (quote === "") { if (comment.charAt(c) === "\"" || comment.charAt(c) === "'") { quote = comment.charAt(c); if (comment.charAt(c + 1) === " " && sourceChar[sourceChar.length - 1] === ":") { sourceChar.push("\\ "); c += 1; } } else { if (comment.charAt(c) === "*" && comment.charAt(c + 1) === "/" && str === "/*prettydiff.com") { break; } if (comment.charAt(c) === "-" && comment.charAt(c + 1) === "-" && comment.charAt(c + 2) === ">" && str === "<!--prettydiff.com") { break; } if (sourceChar[sourceChar.length - 1] !== ":" || (sourceChar[sourceChar.length - 1] === ":" && comment.charAt(c) !== " ")) { sourceChar.push(comment.charAt(c)); } } } else if (comment.charAt(c) === quote) { quote = ""; } } comment = sourceChar .join(""); b = comment.length; for (c = 0; c < b; c += 1) { if ((typeof comment.charAt(c - 1) !== "string" || comment.charAt(c - 1) !== "\\") && (comment.charAt(c) === "\"" || comment.charAt(c) === "'")) { if (quote === "") { quote = comment.charAt(c); } else { quote = ""; } } if (quote === "") { if (comment.charAt(c) === ",") { g = comma + 1; comma = c; if ((/(\:\\\s+)$/).test(comment.slice(g, comma)) === true) { build.push(comment.slice(g, comma).replace(/^(\s*)/, "").replace(/:\\/, ":")); } else { build.push(comment.slice(g, comma).replace(/^(\s*)/, "").replace(/(\s*)$/, "")); } } } } g = comma + 1; comma = comment.length; if ((/(\:\\\s+)$/).test(comment.slice(g, comma)) === true) { build.push(comment.slice(g, comma).replace(/^(\s*)/, "").replace(/:\\/, ":")); } else { build.push(comment.slice(g, comma).replace(/^(\s*)/, "").replace(/(\s*)$/, "")); } quote = ""; b = build.length; sourceChar = []; for (c = 0; c < b; c += 1) { a = build[c].length; for (g = 0; g < a; g += 1) { if (build[c].indexOf(":") === -1) { build[c] = ""; break; } sourceChar = []; if ((typeof build[c].charAt(g - 1) !== "string" || build[c].charAt(g - 1) !== "\\") && (build[c].charAt(g) === "\"" || build[c].charAt(g) === "'")) { if (quote === "") { quote = build[c].charAt(g); } else { quote = ""; } } if (quote === "") { if (build[c].charAt(g) === ":") { sourceChar.push(build[c].substring(0, g).replace(/(\s*)$/, "")); sourceChar.push(build[c].substring(g + 1)); if (sourceChar[1].charAt(0) === sourceChar[1].charAt(sourceChar[1].length - 1) && sourceChar[1].charAt(sourceChar[1].length - 2) !== "\\" && (sourceChar[1].charAt(0) === "\"" || sourceChar[1].charAt(0) === "'")) { sourceChar[1] = sourceChar[1].substring(1, sourceChar[1].length - 1); } build[c] = sourceChar; break; } } } } for (c = 0; c < b; c += 1) { if (typeof build[c][1] === "string") { build[c][0] = build[c][0].replace("api.", ""); if (build[c][0] === "brace_style") { if (build[c][1] === "collapse" || build[c][1] === "collapse-preserve-inline" || build[c][1] === "expand" || build[c][1] === "none") { options.brace_style = build[c][1]; } } if (build[c][0] === "braces" || build[c][0] === "indent") { if (build[c][1] === "knr" || build[c][1] === "allman") { options.braces = build[c][1]; } } else if (build[c][0] === "color") { if (typeof b[c][1] === "string" && b[c][1] !== "") { options.color = b[c][1]; } } else if (build[c][0] === "comments") { if (build[c][1] === "indent" || build[c][1] === "noindent") { options.comments = "noindent"; } } else if (build[c][0] === "diffview") { if (build[c][1] === "sidebyside" || build[c][1] === "inline") { options.diffview = build[c][1]; } } else if (build[c][0] === "endcomma") { if (build[c][1] === "true" || build[c][1] === "always") { options.endcomma = "always"; } else if (build[c][1] === "false" || build[c][1] === "never") { options.endcomma = "never"; } else if (build[c][1] === "multiline") { options.endcomma = "multiline"; } } else if (build[c][0] === "formatArray" || build[c][0] === "formatObject") { if (build[c][1] === "default" || build[c][1] === "indent" || build[c][1] === "inline") { options[build[c][0]] = build[c][1]; } } else if (build[c][0] === "jsscope") { if (build[c][1] === "html" || build[c][1] === "none" || build[c][1] === "report") { options.jsscope = build[c][1]; } } else if (build[c][0] === "lang" || build[c][0] === "langdefault") { options[build[c][0]] = global.prettydiff.language.setlangmode(build[c][1]); } else if (build[c][0] === "mode") { if (build[c][1] === "beautify" || build[c][1] === "minify" || build[c][1] === "diff" || build[c][1] === "parse" || build[c][1] === "analysis") { options.mode = build[c][1]; } } else if (build[c][0] === "objsort") { if (build[c][1] === "all" || build[c][1] === "js" || build[c][1] === "css" || build[c][1] === "markup" || build[c][1] === "none" || build[c][1] === "true" || build[c][1] === "false") { options.objsort = build[c][1]; } } else if (build[c][0] === "parseFormat") { if (build[c][1] === "htmltable" || build[c][1] === "parallel" || build[c][1] === "sequential") { options.parseFormat = build[c][1]; } } else if (build[c][0] === "quoteConvert") { if (build[c][1] === "single" || build[c][1] === "double" || build[c][1] === "none") { options.quoteConvert = build[c][1]; } } else if (build[c][0] === "style") { if (build[c][1] === "indent" || build[c][1] === "noindent") { options.style = build[c][1]; } } else if (build[c][0] === "typescript" && build[c][1] === "true") { options.typescript = true; options.lang = "typescript"; } else if (build[c][0] === "varword") { if (build[c][1] === "each" || build[c][1] === "list" || build[c][1] === "none") { options.varword = build[c][1]; } } else if (build[c][0] === "vertical") { if (build[c][1] === "all" || build[c][1] === "css" || build[c][1] === "js" || build[c][1] === "none") { options.vertical = build[c][1]; } } else if (options[build[c][0]] !== undefined && options[build[c][1]] !== "") { if (build[c][1] === "true") { options[build[c][0]] = true; } else if (build[c][1] === "false") { options[build[c][0]] = false; } else if (isNaN(build[c][1]) === false && (/\s+/).test(build[c][1]) === false) { options[build[c][0]] = Number(build[c][1]); } else { if (options.functions.definitions[build[c][0]].type === "string") { options[build[c][0]] = build[c][1]; } else { options[build[c][0]] = options.functions.definitions[build[c][0]].default; } } } } } }; options.functions.validate = function options_validate(api) { var braceEscape = function diffview__options_braceEscape(input) { return input .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); }; if (options.api !== "dom") { options.functions.default(); } // apacheVelocity - provides support for Apache Velocity markup templates options.apacheVelocity = (api.apacheVelocity === true || api.apacheVelocity === "true"); // determines api source as necessary to make a decision about whether to supply // externally needed JS functions to reports options.api = (api.api === undefined || api.api.length === 0) ? "node" : api.api; // attributetoken - whether attributes should be represented as token items in // the parse table or whether they should be a data properties of their element options.attributetoken = (api.attributetoken === true || api.attributetoken === "true"); // brace-style - provided to emulate JSBeautify's brace-style option options.brace_style = (api.brace_style === "collapse" || api.brace_style === "collapse-preserve-inline" || api.brace_style === "expand") ? api.brace_style : "none"; // braceline - should a new line pad the interior of blocks (curly braces) in // JavaScript options.braceline = (api.braceline === true || api.braceline === "true"); //bracepadding - should curly braces be padded with a space in JavaScript? options.bracepadding = (api.bracepadding === true || api.bracepadding === "true"); // indent - should JSPretty format JavaScript in the normal KNR style or push // curly braces onto a separate line like the "allman" style options.braces = (api.braces === true || api.braces === "true" || api.braces === "allman") ? "allman" : "knr"; //color scheme of generated HTML artifacts options.color = (api.color === "canvas" || api.color === "shadow") ? api.color : "white"; //comments - if comments should receive indentation or not options.comments = (api.comments === "noindent") ? "noindent" : ((api.comments === "nocomment") ? "nocomment" : "indent"); //commline - If in markup a newline should be forced above comments options.commline = (api.commline === true || api.commline === "true"); // compressedcss - If the beautified CSS should contain minified properties options.compressedcss = (api.compressedcss === true || api.compressedcss === "true"); // conditional - should IE conditional comments be preserved during markup // minification options.conditional = (api.conditional === true || api.conditional === "true" || api.html === true); //content - should content be normalized during a diff operation options.content = (api.content === true || api.content === "true"); // context - should the diff report only include the differences, if so then // buffered by how many lines of code options.context = (isNaN(api.context) === true || api.context === "" || Number(api.context) < 0) ? -1 : Number(api.context); //correct - should JSPretty make some corrections for sloppy JS options.correct = (api.correct === true || api.correct === "true"); //crlf - if output should use \r\n (Windows compatible) for line termination options.crlf = (api.crlf === true || api.crlf === "true"); //cssinsertlines = if a new line should be forced between each css block options.cssinsertlines = (api.cssinsertlines === true || api.cssinsertlines === "true"); //csvchar - what character should be used as a separator options.csvchar = (typeof api.csvchar === "string" && api.csvchar.length > 0) ? api.csvchar : ","; //diff - source code to compare with options.diff = (typeof api.diff === "string" && api.diff.length > 0 && (/^(\s+)$/).test(api.diff) === false) ? api.diff : ""; // diffcli - if operating from Node.js and set to true diff output will be // printed to stdout just like git diff options.diffcli = (api.diffcli === true || api.diffcli === "true"); //diffcomments - should comments be included in the diff operation options.diffcomments = (api.diffcomments === true || api.diffcomments === "true"); //difflabel - a text label to describe the diff code options.difflabel = (typeof api.difflabel === "string" && api.difflabel.length > 0) ? braceEscape(api.difflabel) : "New Sample"; // diffspaceignore - If white space differences should be ignored by the diff // tool options.diffspaceignore= (api.diffspaceignore === true || api.diffspaceignore === "true"); // diffview - should the diff report be a single column showing both sources // simultaneously "inline" or showing the sources in separate columns // "sidebyside" options.diffview = (api.diffview === "inline") ? "inline" : "sidebyside"; //dustjs - support for this specific templating scheme options.dustjs = (api.dustjs === true || api.dustjs === "true"); //elseline - for the 'else' keyword onto a new line in JavaScript options.elseline = (api.elseline === true || api.elseline === "true"); // endcomma - if a trailing comma should be injected at the end of arrays and // object literals in JavaScript options.endcomma = (api.endcomma === true || api.endcomma === "true" || api.endcomma === "always") ? "always" : (api.endcomma === "multiline") ? "multiline" : "never"; // endquietly - a node only option to prevent writing anything to console as stdout options.endquietly = (api.endquietly === "log" || api.endquietly === "quiet") ? api.endquietly : ""; // force_attribute - forces indent