Repository: prettier/plugin-xml (js)

Issue:
Support new `singleAttributePerLine` option in Prettier 2.6
### bracketSameLine

false

### printWidth

120

### tabWidth

_No response_

### xmlWhitespaceSensitivity

strict

### xmlSelfClosingSpace

false

### Input XML

```xml
<!-- Can't create a regular issue with the new template, so ~~ab~~using the formatting issue type -->

<xref href="https://github.com/prettier/plugin-xml/issues/2" format="html" scope="external">#2</xref>
```


### Current output XML

```xml
<!-- With "singleAttributePerLine": true in `.prettierrc.json` the output is the same as authored -->

<xref href="https://github.com/prettier/plugin-xml/issues/2" format="html" scope="external">#2</xref>
```


### Expected output XML

```xml
<!-- Print only one attribute per line like in Vue SFC templates, HTML, and JSX -->

<xref
  href="https://github.com/prettier/plugin-xml/issues/2"
  format="html"
  scope="external"
>#2
</xref>
```


Pull request description:
singleAttributePerLine
Closes #448

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad4d209..6542b1d 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]
 
+### Added
+
+- Support for the `singleAttributePerLine` option.
+
 ## [2.0.1] - 2022-03-22
 
 ### Added
diff --git a/README.md b/README.md
index 9ad6cc7..d561bce 100644
--- a/README.md
+++ b/README.md
@@ -46,13 +46,14 @@ The `prettier` executable is now installed and ready for use:
 
 Below are the options (from [`src/plugin.ts`](src/plugin.ts)) that `@prettier/plugin-xml` currently supports:
 
-| API Option                 | CLI Option                     |  Default   | Description                                                                                           |
-| -------------------------- | ------------------------------ | :--------: | ----------------------------------------------------------------------------------------------------- |
-| `bracketSameLine`          | `--bracket-same-line`          |   `true`   | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#bracket-same-line)) |
-| `printWidth`               | `--print-width`                |    `80`    | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)).      |
-| `tabWidth`                 | `--tab-width`                  |    `2`     | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)).        |
-| `xmlSelfClosingSpace`      | `--xml-self-closing-space`     |   `true`   | Adds a space before self-closing tags.                                                                |
-| `xmlWhitespaceSensitivity` | `--xml-whitespace-sensitivity` | `"strict"` | Options are `"strict"` and `"ignore"`. You may want `"ignore"`, [see below](#whitespace).             |
+| API Option                 | CLI Option                     |  Default   | Description                                                                                                   |
+| -------------------------- | ------------------------------ | :--------: | ------------------------------------------------------------------------------------------------------------- |
+| `bracketSameLine`          | `--bracket-same-line`          |   `true`   | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#bracket-same-line))         |
+| `printWidth`               | `--print-width`                |    `80`    | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)).              |
+| `singleAttributePerLine`   | `--single-attribute-per-line`  |  `false`   | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#single-attribute-per-line)) |
+| `tabWidth`                 | `--tab-width`                  |    `2`     | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)).                |
+| `xmlSelfClosingSpace`      | `--xml-self-closing-space`     |   `true`   | Adds a space before self-closing tags.                                                                        |
+| `xmlWhitespaceSensitivity` | `--xml-whitespace-sensitivity` | `"strict"` | Options are `"strict"` and `"ignore"`. You may want `"ignore"`, [see below](#whitespace).                     |
 
 Any of these can be added to your existing [prettier configuration
 file](https://prettier.io/docs/en/configuration.html). For example:
diff --git a/src/printer.ts b/src/printer.ts
index a718e2c..37be674 100644
--- a/src/printer.ts
+++ b/src/printer.ts
@@ -264,8 +264,12 @@ const printer: Printer = {
         const parts: Doc[] = [OPEN[0].image, Name[0].image];
 
         if (attribute) {
+          const separator = opts.singleAttributePerLine ? hardline : line;
           parts.push(
-            indent([line, join(line, path.map(print, "children", "attribute"))])
+            indent([
+              line,
+              join(separator, path.map(print, "children", "attribute"))
+            ])
           );
         }
 


Test patch:
diff --git a/test/__snapshots__/format.test.ts.snap b/test/__snapshots__/format.test.ts.snap
index 072f22d..adbd3a6 100644
--- a/test/__snapshots__/format.test.ts.snap
+++ b/test/__snapshots__/format.test.ts.snap
@@ -227,6 +227,96 @@ use {
 "
 `;
 
+exports[`singleAttributePerLine => true 1`] = `
+"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" ?>
+<!DOCTYPE module PUBLIC \\"-//Puppy Crawl//DTD Check Configuration 1.3//EN\\"
+  \\"https://www.puppycrawl.com/dtds/configuration_1_3.dtd\\">
+<?xml-model href=\\"project.rnc\\" type=\\"application/relax-ng-compact-syntax\\"?>
+<!-- foo -->
+<svg
+  xmlns=\\"http://www.w3.org/2000/svg\\"
+  xmlns:xlink=\\"http://www.w3.org/1999/xlink\\"
+  width=\\"200\\"
+  height=\\"100\\"
+  viewBox=\\"0 0 200 100\\"
+>
+  <title>Style inheritance and the use element</title>
+  <desc _attr=\\"attr\\">
+    &anp; &#12345;
+    <![CDATA[
+      foo
+    ]]>
+    bar
+  </desc>
+  <?pagebreak?>
+
+  <style />
+  <style />
+  <style type=\\"text/css\\">
+circle {
+  stroke-opacity: 0.7;
+}
+.special circle {
+  stroke: green;
+}
+use {
+  stroke: purple;
+  fill: orange;
+}
+  </style>
+
+  <yaml
+    myveryveryveryverylongattributename=\\"myveryveryveryverylongattributevalue\\"
+  >
+    - 1
+    - 2
+    - 3
+  </style>
+
+  <!-- inner comment -->
+
+  <?pagebreak?>
+  <g
+    class=\\"special\\"
+    style=\\"fill: blue\\"
+  >
+    <circle
+      id=\\"c\\"
+      cy=\\"50\\"
+      cx=\\"50\\"
+      r=\\"40\\"
+      stroke-width=\\"20\\"
+    />
+  </g>
+  <use
+    xlink:href=\\"#c\\"
+    x=\\"100\\"
+  />
+  <ignored>
+    <!-- prettier-ignore-start -->
+      <   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 -->
+"
+`;
+
 exports[`xmlSelfClosingSpace => false 1`] = `
 "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
 <!DOCTYPE module PUBLIC \\"-//Puppy Crawl//DTD Check Configuration 1.3//EN\\"
diff --git a/test/format.test.ts b/test/format.test.ts
index 058ff58..15ac1ec 100644
--- a/test/format.test.ts
+++ b/test/format.test.ts
@@ -52,3 +52,12 @@ test("bracketSameLine => true, xmlSelfClosingSpace => false", () => {
 
   expect(formatted).toMatchSnapshot();
 });
+
+test("singleAttributePerLine => true", () => {
+  const formatted = format(fixture, {
+    singleAttributePerLine: true,
+    xmlWhitespaceSensitivity: "ignore"
+  });
+
+  expect(formatted).toMatchSnapshot();
+});