UNPKG

liberty-prettydiff

Version:

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

923 lines (918 loc) 247 kB
/*prettydiff.com api.topcoms:true,api.insize:4,api.inchar:" ",api.vertical:true */ /*jshint laxbreak: true*/ /*global __dirname, ace, define, global, module, process, require*/ /*********************************************************************** markuppretty is written by Austin Cheney on 20 Jun 2015. Anybody may use this code without permission so long as this comment exists verbatim in each instance of its use. http://mailmarkup.org/ http://prettydiff.com/ **********************************************************************/ /* A simple parser for XML, HTML, and a variety of template schemes. It beautifies, minifies, and peforms a series of analysis*/ (function markuppretty_init() { "use strict"; var markuppretty = function markuppretty_(options) { var safeSort = global.prettydiff.safeSort, output = "", stats = { cdata : [ 0, 0 ], comment : [ 0, 0 ], conditional: [ 0, 0 ], content : [ 0, 0 ], end : [ 0, 0 ], ignore : [ 0, 0 ], script : [ 0, 0 ], sgml : [ 0, 0 ], singleton : [ 0, 0 ], space : 0, start : [ 0, 0 ], style : [ 0, 0 ], template : [ 0, 0 ], text : [ 0, 0 ], xml : [ 0, 0 ] }, //parallel arrays // * attrs is a list of arrays, each of which contains (if any) parsed attributes // * begin stores the index of the current token's parent element // * daddy stores the tag name of the parent element // * jscom stores true/false if the current token is a JS comment from JSX format // * level describes the indentation of a given token level is only used in // beautify and diff modes // * linen stores the input line number on which the token occurs // * lines describes the preceeding space using: 2, 1, or 0 lines is populated in // markuppretty__tokenize_spacer // * presv whether a given token should be preserved as provided // * token stores parsed tokens // * types segments tokens into named groups // * value attribute value if current type is attribute and options.attributetoken is true attrs = [], jscom = [], level = [], linen = [], lines = [], token = [], types = [], presv = [], daddy = [], begin = [], value = [], reqs = [], ids = [], parseError = [], parent = [["none", -1]], line = 1, wrap = options.wrap, objsortop = false, globalerror = "", lf = (options.crlf === true || options.crlf === "true") ? "\r\n" : "\n", sourceSize = options.source.length, extlib = function markuppretty__extlib(type) { var result = ""; if (type === "script" && typeof global.prettydiff.jspretty !== "function") { return options.source; } if (type === "style" && typeof global.prettydiff.csspretty !== "function") { return options.source; } result = (type === "script") ? global.prettydiff.jspretty(options) : global.prettydiff.csspretty(options); if (options.nodeasync === true) { if (globalerror === "") { globalerror = result[1]; } if (options.mode === "parse") { if (options.parseFormat === "htmltable") { if (type === "script") { return result[0].data.replace("<thead>", "<thead><tr><th colspan=\"6\" class=\"nested\">JavaScript tokens</th></tr>"); } return result[0].data.replace("<thead>", "<thead><tr><th colspan=\"4\" class=\"nested\">CSS tokens</th></tr>"); } return result[0].data; } return result[0]; } if (options.mode === "parse") { if (options.parseFormat === "htmltable") { if (type === "script") { return result.data.replace("<thead>", "<thead><tr><th colspan=\"6\" class=\"nested\">JavaScript tokens</th></tr>"); } return result.data.replace("<thead>", "<thead><tr><th colspan=\"4\" class=\"nested\">CSS tokens</th></tr>"); } return result.data; } return result; }, //What is the lowercase tag name of the provided token? tagName = function markuppretty__tagName(el) { var space = el .replace(/^(\{((%-?)|\{-?)\s*)/, "%") .replace(/\s+/, " ") .indexOf(" "), name = (space < 0) ? el .replace(/^(\{((%-?)|\{-?)\s*)/, " ") .slice(1, el.length - 1) .toLowerCase() : el .replace(/^(\{((%-?)|\{-?)\s*)/, " ") .slice(1, space) .toLowerCase(); name = name.replace(/(\}\})$/, ""); if (name.indexOf("(") > 0) { name = name.slice(0, name.indexOf("(")); } return name; }; (function markuppretty__options() { objsortop = (options.objsort === true || options.objsort === "true" || options.objsort === "all" || options.objsort === "markup"); options.source = (typeof options.source === "string" && options.source.length > 0) ? options .source .replace(/\r\n?/g, "\n") : "Error: no source code supplied to markuppretty!"; if (options.mode === "analysis") { options.accessibility = true; } }()); //type definitions: // * start end type // * <![CDATA[ ]]> cdata // * <!-- --> comment // * <#-- --> comment // * <%-- --%> comment // * {! !} comment // * <!--[if --> conditional // * text text content // * </ > end // * <pre </pre> ignore (html only) // * text text script // * <! > sgml // * < /> singleton // * < > start // * text text style // * <!--# --> template // * <% %> template // * {{{ }}} template // * {{ }} template // * {% %} template // * [% %] template // * {@ @} template // * {# #} template // * {# /} template // * {? /} template // * {^ /} template // * {@ /} template // * {< /} template // * {+ /} template // * {~ } template // * <? ?> template // * {:else} template_else // * <#else > template_else // * {@}else{@} template_else // * <%}else{%> template_else // * {{ }} template_end // * <%\s*} %> template_end // * [%\s*} %] template_end // * {@\s*} @} template_end // * { } template_end // * {{# }} template_start // * <% {\s*%> template_start // * [% {\s*%] template_start // * {@ {\s*@} template_start // * {# } template_start // * {? } template_start // * {^ } template_start // * {@ } template_start // * {< } template_start // * {+ } template_start // * <?xml ?> xml if (options.mode !== "diff") { options.content = false; } if (options.jsx === true) { options.dustjs = false; } (function markuppretty__tokenize() { var a = 0, b = options .source .split(""), c = b.length, minspace = "", space = "", list = 0, litag = 0, linepreserve = 0, cftransaction = false, sgmlflag = 0, ext = false, //cftags is a list of supported coldfusion tags //* required - means must have a separate matching end tag // * optional - means the tag could have a separate end tag, but is probably a // singleton //* prohibited - means there is not corresponding end tag cftags = { cfabort : "prohibited", cfajaximport : "optional", cfajaxproxy : "optional", cfapplet : "prohibited", cfapplication : "prohibited", cfargument : "prohibited", cfassociate : "prohibited", cfauthenticate : "prohibited", cfbreak : "prohibited", cfcache : "optional", cfcalendar : "optional", cfcase : "required", cfcatch : "required", cfchart : "optional", cfchartdata : "prohibited", cfchartseries : "optional", cfclient : "required", cfclientsettings : "optional", cfcol : "prohibited", cfcollection : "prohibited", cfcomponent : "required", cfcontent : "optional", cfcontinue : "prohibited", cfcookie : "prohibited", cfdbinfo : "prohibited", cfdefaultcase : "required", cfdirectory : "prohibited", cfdiv : "optional", cfdocument : "optional", cfdocumentitem : "optional", cfdocumentsection : "optional", cfdump : "optional", cfelse : "prohibited", cfelseif : "prohibited", cferror : "prohibited", cfexchangecalendar : "optional", cfexchangeconnection : "optional", cfexchangecontact : "optional", cfexchangeconversation: "optional", cfexchangefilter : "optional", cfexchangefolder : "optional", cfexchangemail : "optional", cfexchangetask : "optional", cfexecute : "required", cfexit : "prohibited", cffeed : "prohibited", cffile : "optional", cffileupload : "optional", cffinally : "required", cfflush : "prohibited", cfform : "required", cfformgroup : "required", cfformitem : "optional", cfforward : "prohibited", cfftp : "prohibited", cffunction : "required", cfgraph : "required", cfgraphdata : "prohibited", cfgrid : "required", cfgridcolumn : "optional", cfgridrow : "optional", cfgridupdate : "optional", cfheader : "prohibited", cfhtmlbody : "optional", cfhtmlhead : "optional", cfhtmltopdf : "optional", cfhtmltopdfitem : "optional", cfhttp : "optional", cfhttpparam : "prohibited", cfif : "required", cfimage : "prohibited", cfimap : "prohibited", cfimapfilter : "optional", cfimport : "prohibited", cfinclude : "prohibited", cfindex : "prohibited", cfinput : "prohibited", cfinsert : "prohibited", cfinterface : "required", cfinvoke : "optional", cfinvokeargument : "prohibited", cflayout : "optional", cflayoutarea : "optional", cfldap : "prohibited", cflocation : "prohibited", cflock : "required", cflog : "prohibited", cflogic : "required", cfloginuser : "prohibited", cflogout : "prohibited", cfloop : "required", cfmail : "required", cfmailparam : "prohibited", cfmailpart : "required", cfmap : "optional", cfmapitem : "optional", cfmediaplayer : "optional", cfmenu : "required", cfmenuitem : "optional", cfmessagebox : "optional", cfmodule : "optional", cfNTauthenticate : "optional", cfoauth : "optional", cfobject : "prohibited", cfobjectcache : "prohibited", cfoutput : "required", cfpageencoding : "optional", cfparam : "prohibited", cfpdf : "optional", cfpdfform : "optional", cfpdfformparam : "optional", cfpdfparam : "prohibited", cfpdfsubform : "required", cfpod : "optional", cfpop : "prohibited", cfpresentation : "required", cfpresentationslide : "optional", cfpresenter : "optional", cfprint : "optional", cfprocessingdirective : "optional", cfprocparam : "prohibited", cfprocresult : "prohibited", cfprogressbar : "optional", cfproperty : "prohibited", cfquery : "required", cfqueryparam : "prohibited", cfregistry : "prohibited", cfreport : "optional", cfreportparam : "optional", cfrethrow : "prohibited", cfretry : "prohibited", cfreturn : "prohibited", cfsavecontent : "required", cfschedule : "prohibited", cfscript : "required", cfsearch : "prohibited", cfselect : "required", cfservlet : "prohibited", cfservletparam : "prohibited", cfset : "prohibited", cfsetting : "optional", cfsharepoint : "optional", cfsilent : "required", cfsleep : "prohibited", cfslider : "prohibited", cfspreadsheet : "optional", cfsprydataset : "optional", cfstatic : "required", cfstopwatch : "required", cfstoredproc : "optional", cfswitch : "required", cftable : "required", cftextarea : "optional", cfthread : "optional", cfthrow : "prohibited", cftimer : "required", cftooltip : "required", cftrace : "optional", cftransaction : "required", cftree : "required", cftreeitem : "optional", cftry : "required", cfupdate : "prohibited", cfvideo : "prohibited", cfvideoplayer : "optional", cfwddx : "prohibited", cfwebsocket : "optional", cfwhile : "required", cfwindow : "optional", cfx_ : "prohibited", cfxml : "required", cfzip : "optional", cfzipparam : "prohibited" }, // determine if spaces between nodes are absent, multiline, or merely there 2 - // multiline 1 - space present 0 - no space present spacer = function markuppretty__tokenize_spacer() { var linea = 0; if (space.length > 0) { stats.space += space.length; linea = space .split("\n") .length - 1; if (options.preserve > 0 && linea > 1) { if (linea > options.preserve + 1) { lines.push(options.preserve + 1); } else { lines.push(linea); } } else { lines.push(1); } } else { lines.push(0); } minspace = space; space = ""; }, //parses tags, attributes, and template elements tag = function markuppretty__tokenize_tag(end) { var lexer = [], bcount = 0, e = 0, f = 0, igcount = 0, jsxcount = 0, braccount = 0, parncount = 0, quote = "", element = "", lastchar = "", jsxquote = "", tname = "", comment = false, cheat = false, endtag = false, nopush = false, nosort = false, simple = false, preserve = false, stest = false, liend = false, ignoreme = false, quotetest = false, parseFail = false, singleton = false, earlyexit = false, attribute = [], attstore = [], presend = { cfquery: true }, arname = function markuppretty__tokenize_tag_name(x) { var eq = x.indexOf("="); if (eq > 0 && ((eq < x.indexOf("\"") && x.indexOf("\"") > 0) || (eq < x.indexOf("'") && x.indexOf("'") > 0))) { return x.slice(0, eq); } return x; }, slashy = function markuppretty__tokenize_tag_slashy() { var x = a; do { x -= 1; } while (b[x] === "\\"); x = a - x; if (x % 2 === 1) { return false; } return true; }, attrpush = function markuppretty__tokenize_tag_attrpush(quotes) { var atty = "", name = "", aa = 0, bb = 0; if (quotes === true) { if (quote === "\"" && options.quoteConvert === "single") { atty = attribute .slice(0, attribute.length - 1) .join("") .replace(/'/g, "\"") .replace(/"/, "'") + "'"; } else if (quote === "'" && options.quoteConvert === "double") { atty = attribute .slice(0, attribute.length - 1) .join("") .replace(/"/g, "'") .replace(/'/, "\"") + "\""; } else { atty = attribute.join(""); } name = arname(atty); if (name === "data-prettydiff-ignore") { ignoreme = true; } else if (name === "id") { ids.push(atty.slice(name.length + 2, atty.length - 1)); } else if (name === "schemaLocation") { reqs.push(atty.slice(name.length + 2, atty.length - 1)); } quote = ""; } else { atty = attribute .join("") .replace(/\s+/g, " "); name = arname(atty); if (name === "data-prettydiff-ignore") { ignoreme = true; } else if (name === "id") { ids.push(element.slice(name.length + 1, atty.length)); } if (options.jsx === true && attribute[0] === "{" && attribute[attribute.length - 1] === "}") { jsxcount = 0; } } if (atty.slice(0, 3) === "<%=" || atty.slice(0, 2) === "{%") { nosort = true; } atty = atty .replace(/^\u0020/, "") .replace(/\u0020$/, ""); attribute = atty .replace(/\r\n/g, "\n") .split("\n"); bb = attribute.length; for (aa = 0; aa < bb; aa += 1) { attribute[aa] = attribute[aa].replace(/(\s+)$/, ""); } atty = attribute.join(lf); if (atty === "=") { attstore[attstore.length - 1] = attstore[attstore.length - 1] + "="; } else if (atty.charAt(0) === "=" && attstore.length > 0 && attstore[attstore.length - 1].indexOf("=") < 0) { //if an attribute starts with a `=` then adjoin it to the last attribute attstore[attstore.length - 1] = attstore[attstore.length - 1] + atty; } else if (atty.charAt(0) !== "=" && attstore.length > 0 && attstore[attstore.length - 1].indexOf("=") === attstore[attstore.length - 1].length - 1) { // if an attribute follows an attribute ending with `=` then adjoin it to the // last attribute attstore[attstore.length - 1] = attstore[attstore.length - 1] + atty; } else if (atty !== "" && atty !== " ") { attstore.push(atty); } attribute = []; }; spacer(); jscom.push(false); linen.push(line); value.push(""); ext = false; // this complex series of conditions determines an elements delimiters look to // the types being pushed to quickly reason about the logic no type is pushed // for start tags or singleton tags just yet some types set the `preserve` flag, // which means to preserve internal white space The `nopush` flag is set when // parsed tags are to be ignored and forgotten (function markuppretty__tokenize_types() { if (end === "]>") { end = ">"; sgmlflag -= 1; types.push("template_end"); } else if (end === "---") { preserve = true; types.push("comment"); } else if (b[a] === "<") { if (b[a + 1] === "/") { if (b[a + 2] === "#") { types.push("template_end"); } else { types.push("end"); } end = ">"; } else if (b[a + 1] === "!") { if (b[a + 2] === "-" && b[a + 3] === "-") { if (b[a + 4] === "#") { end = "-->"; types.push("template"); } else if (b[a + 4] === "[" && b[a + 5] === "i" && b[a + 6] === "f" && options.conditional === true) { end = "-->"; types.push("conditional"); } else if (b[a + 4] === "-" && (/<cf[a-z]/i).test(options.source) === true) { preserve = true; comment = true; end = "--->"; types.push("comment"); } else { end = "-->"; if (options.mode === "minify" || options.comments === "nocomment") { nopush = true; comment = true; } else { preserve = true; comment = true; if (options.commline === true) { lines[lines.length - 1] = 2; } types.push("comment"); } } } else if (b[a + 2] === "[" && b[a + 3] === "C" && b[a + 4] === "D" && b[a + 5] === "A" && b[a + 6] === "T" && b[a + 7] === "A" && b[a + 8] === "[") { end = "]]>"; preserve = true; comment = true; types.push("cdata"); } else { end = ">"; sgmlflag += 1; types.push("sgml"); } } else if (b[a + 1] === "?") { end = "?>"; if (b[a + 2] === "x" && b[a + 3] === "m" && b[a + 4] === "l") { types.push("xml"); } else { preserve = true; types.push("template"); } } else if (b[a + 1] === "%") { if (b[a + 2] !== "=") { preserve = true; } if (b[a + 2] === "-" && b[a + 3] === "-") { end = "--%>"; comment = true; if (options.commline === true) { line[line.length - 1] = 2; } types.push("comment"); } else if (b[a + 2] === "#") { end = "%>"; comment = true; if (options.commline === true) { line[line.length - 1] = 2; } types.push("comment"); } else { end = "%>"; types.push("template"); } } else if (b[a + 4] !== undefined && b[a + 1].toLowerCase() === "p" && b[a + 2].toLowerCase() === "r" && b[a + 3].toLowerCase() === "e" && (b[a + 4] === ">" || (/\s/).test(b[a + 4]) === true)) { end = "</pre>"; preserve = true; types.push("ignore"); } else if (b[a + 4] !== undefined && b[a + 1].toLowerCase() === "x" && b[a + 2].toLowerCase() === "s" && b[a + 3].toLowerCase() === "l" && b[a + 4].toLowerCase() === ":" && b[a + 5].toLowerCase() === "t" && b[a + 6].toLowerCase() === "e" && b[a + 7].toLowerCase() === "x" && b[a + 8].toLowerCase() === "t" && (b[a + 9] === ">" || (/\s/).test(b[a + 9]) === true)) { end = "</xsl:text>"; preserve = true; types.push("ignore"); } else if (b[a + 8] !== undefined && b[a + 1].toLowerCase() === "c" && b[a + 2].toLowerCase() === "f" && b[a + 3].toLowerCase() === "q" && b[a + 4].toLowerCase() === "u" && b[a + 5].toLowerCase() === "e" && b[a + 6].toLowerCase() === "r" && b[a + 7].toLowerCase() === "y" && (b[a + 8] === ">" || (/\s/).test(b[a + 8]))) { end = ">"; linepreserve += 1; types.push("linepreserve"); } else if (b[a + 1] === "<") { if (b[a + 2] === "<") { end = ">>>"; } else { end = ">>"; } types.push("template"); } else if (b[a + 1] === "#") { if (b[a + 2] === "e" && b[a + 3] === "l" && b[a + 4] === "s" && b[a + 5] === "e") { end = ">"; types.push("template_else"); } else if (b[a + 2] === "-" && b[a + 3] === "-") { end = "-->"; types.push("comment"); preserve = true; } else { end = ">"; types.push("template_start"); } } else { simple = true; end = ">"; } } else if (b[a] === "{") { preserve = true; if (options.jsx === true) { end = "}"; types.push("script"); } else if (options.dustjs === true) { if (b[a + 1] === ":" && b[a + 2] === "e" && b[a + 3] === "l" && b[a + 4] === "s" && b[a + 5] === "e" && b[a + 6] === "}") { a += 6; token.push("{:else}"); presv.push(true); daddy.push(parent[parent.length - 1][0]); begin.push(parent[parent.length - 1][1]); attrs.push({}); stats.template[0] += 1; stats.template[1] += 7; earlyexit = true; return types.push("template_else"); } if (b[a + 1] === "!") { end = "!}"; comment = true; types.push("comment"); } else if (b[a + 1] === "/") { end = "}"; types.push("template_end"); } else if (b[a + 1] === "~") { end = "}"; types.push("singleton"); } else if (b[a + 1] === ">") { end = "/}"; types.push("singleton"); } else if (b[a + 1] === "#" || b[a + 1] === "?" || b[a + 1] === "^" || b[a + 1] === "@" || b[a + 1] === "<" || b[a + 1] === "+") { end = "}"; types.push("template_start"); } else { end = "}"; types.push("template"); } } else if (b[a + 1] === "{") { if (b[a + 2] === "{") { end = "}}}"; types.push("template"); } else if (b[a + 2] === "#") { end = "}}"; types.push("template_start"); } else if (b[a + 2] === "/") { end = "}}"; types.push("template_end"); } else if (b[a + 2] === "e" && b[a + 3] === "n" && b[a + 4] === "d") { end = "}}"; types.push("template_end"); } else if (b[a + 2] === "e" && b[a + 3] === "l" && b[a + 4] === "s" && b[a + 5] === "e") { end = "}}"; types.push("template_else"); } else { end = "}}"; types.push("template"); } } else if (b[a + 1] === "%") { end = "%}"; types.push("template"); } else if (b[a + 1] === "#") { end = "#}"; types.push("comment"); preserve = true; comment = true; } else { end = b[a + 1] + "}"; types.push("template"); } if (b[a + 1] === "@" && b[a + 2] === "}" && b[a + 3] === "e" && b[a + 4] === "l" && b[a + 5] === "s" && b[a + 6] === "e" && b[a + 7] === "{" && b[a + 8] === "@" && b[a + 9] === "}") { a += 9; types[types.length - 1] = "template_else"; presv.push(true); daddy.push(parent[parent.length - 1][0]); begin.push(parent[parent.length - 1][1]); attrs.push({}); stats.template[0] += 1; stats.template[1] += 10; earlyexit = true; return token.push("{@}else{@}"); } } else if (b[a] === "[" && b[a + 1] === "%") { end = "%]"; types.push("template"); } else if (b[a] === "#" && options.apacheVelocity === true) { if (b[a + 1] === "*") { preserve = true; comment = true; end = "*#"; types.push("comment"); } else if (b[a + 1] === "[" && b[a + 2] === "[") { preserve = true; comment = true; end = "]]#"; types.push("comment"); } else if (b[a + 1] === "#") { preserve = true; comment = true; end = "\n"; types.push("comment"); } else if (b[a + 1] === "e" && b[a + 2] === "l" && b[a + 3] === "s" && b[a + 4] === "e" && (/\s/).test(b[a + 5]) === true) { end = "\n"; types.push("template_else"); } else if (b[a + 1] === "i" && b[a + 2] === "f") { end = "\n"; types.push("template_start"); } else if (b[a + 1] === "f" && b[a + 2] === "o" && b[a + 3] === "r" && b[a + 4] === "e" && b[a + 5] === "a" && b[a + 6] === "c" && b[a + 7] === "h") { end = "\n"; types.push("template_start"); } else if (b[a + 1] === "e" && b[a + 2] === "n" && b[a + 3] === "d") { end = "\n"; types.push("template_end"); } else { end = "\n"; types.push("template"); } } else if (b[a] === "$" && options.apacheVelocity === true) { end = "\n"; types.push("template"); } if (options.unformatted === true) { preserve = true; } }()); if (earlyexit === true) { return; } // This loop is the logic that parses tags and attributes If the attribute // data-prettydiff-ignore is present the `ignore` flag is set The ignore flag is // identical to the preserve flag lastchar = end.charAt(end.length - 1); for (a = a; a < c; a += 1) { if (b[a] === "\n") { line += 1; } if (preserve === true || (/\s/).test(b[a]) === false) { lexer.push(b[a]); } else if (lexer[lexer.length - 1] !== " ") { lexer.push(" "); } if (comment === true) { quote = ""; //comments must ignore fancy encapsulations and attribute parsing if (b[a] === lastchar && lexer.length > end.length + 1) { //if current character matches the last character of the tag ending sequence f = lexer.length; for (e = end.length - 1; e > -1; e -= 1) { f -= 1; if (lexer[f] !== end.charAt(e)) { break; } } if (e < 0) { if (end === "endcomment") { f -= 1; if ((/\s/).test(lexer[f]) === true) { do { f -= 1; } while ((/\s/).test(lexer[f]) === true); } if (lexer[f - 1] === "{" && lexer[f] === "%") { end = "%}"; lastchar = "}"; } } else { break; } } } } else { if (quote === "") { if (options.jsx === true) { if (b[a] === "{") { jsxcount += 1; } else if (b[a] === "}") { jsxcount -= 1; } } if (types[types.length - 1] === "sgml" && b[a] === "[" && lexer.length > 4) { types[types.length - 1] = "template_start"; break; } if (b[a] === "<" && preserve === false && lexer.length > 1 && end !== ">>" && end !== ">>>" && simple === true) { parseError.push("Parse error on line " + line + " on element: "); parseFail = true; } if (stest === true && (/\s/).test(b[a]) === false && b[a] !== lastchar) { //attribute start stest = false; quote = jsxquote; igcount = 0; lexer.pop(); for (a = a; a < c; a += 1) { if (b[a] === "\n") { line += 1; } if (options.unformatted === true) { lexer.push(b[a]); } attribute.push(b[a]); if ((b[a] === "<" || b[a] === ">") && (quote === "" || quote === ">") && options.jsx === false) { if (quote === "" && b[a] === "<") { quote = ">"; braccount = 1; } else if (quote === ">") { if (b[a] === "<") { braccount += 1; } else if (b[a] === ">") { braccount -= 1; if (braccount === 0) { // the following detects if a coldfusion tag is embedded within another markup // tag tname = tagName(attribute.join("")); if (cftags[tname] === "required") { quote = "</" + tname + ">"; } else { quote = ""; igcount = 0; attrpush(false); break; }