diff --git a/src/formatting/formatters/v2-xml-formatter.ts b/src/formatting/formatters/v2-xml-formatter.ts index 3f85734..e6d21b7 100644 --- a/src/formatting/formatters/v2-xml-formatter.ts +++ b/src/formatting/formatters/v2-xml-formatter.ts @@ -5,7 +5,18 @@ import { ClassicXmlFormatter } from "./classic-xml-formatter"; /* tslint:disable no-use-before-declare */ export class V2XmlFormatter implements XmlFormatter { formatXml(xml: string, options: XmlFormattingOptions): string { - xml = this.minifyXml(xml, options); + // remove whitespace from between tags, except for line breaks + xml = xml.replace(/>\s{0,} { // spaces between the node name and the first attribute + return match.replace(/[^\S\r\n]/g, ""); + }); + + // do some light minification to get rid of insignificant whitespace + xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes + xml = xml.replace(/"\s+(?=>)/g, "\""); // spaces between the last attribute and tag close (>) + xml = xml.replace(/"\s+(?=\/>)/g, "\" "); // spaces between the last attribute and tag close (/>) + xml = xml.replace(/[^ <>="]\s+[^ <>="]+=/g, (match: string) => { // spaces between the node name and the first attribute + return match.replace(/\s+/g, " "); + }); let output = ""; @@ -133,15 +144,15 @@ export class V2XmlFormatter implements XmlFormatter { else if (location === Location.Text && cc === "<" && nc === "/") { indentLevel--; - // if the end tag immediately follows another end tag, add a line break and indent // if the end tag immediately follows a line break, just add an indentation + // if the end tag immediately follows another end tag, add a line break and indent // otherwise, this should be treated as a same-line end tag(ex. text) - if (lastNonTextLocation === Location.EndTag) { - output += `${options.newLine}${this._getIndent(options, indentLevel)}<`; + if (pc === "\n") { + output += `${this._getIndent(options, indentLevel)}<`; } - else if (pc === "\n") { - output += `${this._getIndent(options, indentLevel)}<`; + else if (lastNonTextLocation === Location.EndTag) { + output += `${options.newLine}${this._getIndent(options, indentLevel)}<`; } else { diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 7f51b01..8d12984 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -40,6 +40,14 @@ describe("V2XmlFormatter", () => { testFormatter(xmlFormatter, options, "text-only-line"); }); + it("should handle preformatted xml", () => { + testFormatter(xmlFormatter, options, "preformatted"); + }); + + it ("should preserve line breaks between elements", () => { + testFormatter(xmlFormatter, options, "preserve-breaks"); + }); + }); }); diff --git a/src/test/test-data/preformatted.formatted.xml b/src/test/test-data/preformatted.formatted.xml new file mode 100644 index 0000000..6b3c12e --- /dev/null +++ b/src/test/test-data/preformatted.formatted.xml @@ -0,0 +1,9 @@ + + text + text + text + text + + text + + \ No newline at end of file diff --git a/src/test/test-data/preformatted.unformatted.xml b/src/test/test-data/preformatted.unformatted.xml new file mode 100644 index 0000000..6b3c12e --- /dev/null +++ b/src/test/test-data/preformatted.unformatted.xml @@ -0,0 +1,9 @@ + + text + text + text + text + + text + + \ No newline at end of file diff --git a/src/test/test-data/preserve-breaks.formatted.xml b/src/test/test-data/preserve-breaks.formatted.xml new file mode 100644 index 0000000..e8d02b4 --- /dev/null +++ b/src/test/test-data/preserve-breaks.formatted.xml @@ -0,0 +1,12 @@ + + text + text + + text + text + + + text + + + \ No newline at end of file diff --git a/src/test/test-data/preserve-breaks.unformatted.xml b/src/test/test-data/preserve-breaks.unformatted.xml new file mode 100644 index 0000000..e8d02b4 --- /dev/null +++ b/src/test/test-data/preserve-breaks.unformatted.xml @@ -0,0 +1,12 @@ + + text + text + + text + text + + + text + + + \ No newline at end of file