Repository: prettier/plugin-xml
Pull request #103 (2020-07-21 15:45:05)

Address indentation on mixed content


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 230b39c..7acb9b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
 
 ## [Unreleased]
 
+### Changed
+
+- Some better support for indenting mixed content when whitespace is set to ignore.
+
 ## [0.9.0] - 2020-07-21
 
 ### Added
diff --git a/src/print.js b/src/print.js
index d797e4f..afb790c 100644
--- a/src/print.js
+++ b/src/print.js
@@ -1,5 +1,6 @@
 const {
   concat,
+  fill,
   group,
   hardline,
   indent,
@@ -31,16 +32,10 @@ const hasIgnoreRanges = (comments) => {
   return false;
 };
 
-const elementOnly = (node) => {
-  const { CData, Comment, chardata, element, reference } = node.children;
+const whitespaceIgnorable = (node) => {
+  const { CData, Comment, reference } = node.children;
 
-  return (
-    !CData &&
-    (!chardata || chardata.every((datum) => !datum.children.TEXT)) &&
-    element &&
-    !reference &&
-    !hasIgnoreRanges(Comment)
-  );
+  return !CData && !reference && !hasIgnoreRanges(Comment);
 };
 
 const printCData = (node) => ({
@@ -252,17 +247,47 @@ const nodes = {
       concat([SLASH_OPEN[0].image, END_NAME[0].image, END[0].image])
     );
 
-    // If we're ignoring whitespace and we're printing a node that only contains
-    // other elements, then we can just print out the child elements directly.
-    if (opts.xmlWhitespaceSensitivity === "ignore" && elementOnly(content[0])) {
+    if (
+      opts.xmlWhitespaceSensitivity === "ignore" &&
+      whitespaceIgnorable(content[0])
+    ) {
       const {
         Comment = [],
-        element,
+        chardata = [],
+        element = [],
         PROCESSING_INSTRUCTION = []
       } = content[0].children;
 
+      const chardatas = [];
+      chardata.forEach((chardatum) => {
+        if (chardatum.children.TEXT) {
+          const content = chardatum.children.TEXT[0].image.trim();
+          const printed = group(
+            concat(
+              content.split(/(\n)/g).map((value) => {
+                if (value === "\n") {
+                  return literalline;
+                }
+
+                return fill(
+                  value
+                    .split(/( )/g)
+                    .map((segment, index) => (index % 2 === 0 ? segment : line))
+                );
+              })
+            )
+          );
+
+          chardatas.push({
+            offset: chardatum.location.startOffset,
+            printed
+          });
+        }
+      });
+
       const children = []
         .concat(Comment.map(printComment))
+        .concat(chardatas)
         .concat(
           element.map((node, index) => ({
             offset: node.location.startOffset,
@@ -281,11 +306,14 @@ const nodes = {
         .sort((left, right) => left.offset - right.offset)
         .map(({ printed }) => printed);
 
+      const separator =
+        children.length == 1 && chardatas.length == 1 ? softline : hardline;
+
       return group(
         concat([
           openTag,
-          indent(concat([hardline, join(hardline, children)])),
-          hardline,
+          indent(concat([separator, join(separator, children)])),
+          separator,
           closeTag
         ])
       );


Test patch:
diff --git a/test/__snapshots__/format.test.js.snap b/test/__snapshots__/format.test.js.snap
index 501c6c5..cb393c7 100644
--- a/test/__snapshots__/format.test.js.snap
+++ b/test/__snapshots__/format.test.js.snap
@@ -39,6 +39,16 @@ exports[`defaults 1`] = `
       <   ignored   />
     <!-- prettier-ignore-end -->
   </ignored>
+  <p>
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at est eget enim consectetur accumsan. Aliquam pretium sodales ipsum quis dignissim. Sed id sem vel diam luctus fringilla. Aliquam quis egestas magna. Curabitur molestie lorem et odio porta, et molestie libero laoreet. Morbi rhoncus sagittis cursus. Nullam vehicula pretium consequat. Praesent porta ante at posuere sollicitudin. Nullam commodo tempor arcu, at condimentum neque elementum ut.
+  </p>
+  <span>
+    content
+  </span>
+  <div>
+    even more
+    <content />
+  </div>
 </svg>
 <!-- bar -->
 "
@@ -83,6 +93,20 @@ exports[`xmlWhitespaceSensitivity => ignore 1`] = `
       <   ignored   />
     <!-- prettier-ignore-end -->
   </ignored>
+  <p>
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at est eget
+    enim consectetur accumsan. Aliquam pretium sodales ipsum quis dignissim. Sed
+    id sem vel diam luctus fringilla. Aliquam quis egestas magna. Curabitur
+    molestie lorem et odio porta, et molestie libero laoreet. Morbi rhoncus
+    sagittis cursus. Nullam vehicula pretium consequat. Praesent porta ante at
+    posuere sollicitudin. Nullam commodo tempor arcu, at condimentum neque
+    elementum ut.
+  </p>
+  <span>content</span>
+  <div>
+    even more
+    <content />
+  </div>
 </svg>
 <!-- bar -->
 "
diff --git a/test/fixture.xml b/test/fixture.xml
index 52911cf..a1f24b2 100644
--- a/test/fixture.xml
+++ b/test/fixture.xml
@@ -36,5 +36,15 @@
       <   ignored   />
     <!-- prettier-ignore-end -->
   </ignored>
+  <p>
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at est eget enim consectetur accumsan. Aliquam pretium sodales ipsum quis dignissim. Sed id sem vel diam luctus fringilla. Aliquam quis egestas magna. Curabitur molestie lorem et odio porta, et molestie libero laoreet. Morbi rhoncus sagittis cursus. Nullam vehicula pretium consequat. Praesent porta ante at posuere sollicitudin. Nullam commodo tempor arcu, at condimentum neque elementum ut.
+  </p>
+  <span>
+    content
+  </span>
+  <div>
+    even more
+    <content />
+  </div>
 </svg>
 <!-- bar -->