diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md
index 7b5a8f5b..764e3973 100644
--- a/CHANGELOG.unreleased.md
+++ b/CHANGELOG.unreleased.md
@@ -41,3 +41,33 @@ Examples:
```
-->
+
+- Markdown: Do not align table contents if it exceeds the print width and `--prose-wrap never` is set ([#5701] by [@chenshuai2144])
+
+ The aligned table is less readable than the compact one
+ if it's particularly long and the word wrapping is not enabled in the editor
+ so we now print them as compact tables in these situations.
+
+
+ ```md
+
+ | Property | Description | Type | Default |
+ | -------- | ----------- | ---- | ------- |
+ | bordered | Toggles rendering of the border around the list | boolean | false |
+ | itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - |
+
+
+ | Property | Description | Type | Default |
+ | ---------- | --------------------------------------------------------------------------------------------------------------------- | ------- | ------- |
+ | bordered | Toggles rendering of the border around the list | boolean | false |
+ | itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - |
+
+
+ | Property | Description | Type | Default |
+ | --- | --- | --- | --- |
+ | bordered | Toggles rendering of the border around the list | boolean | false |
+ | itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - |
+ ```
+
+[@chenshuai2144]: https://github.com/chenshuai2144
+[#5701]: https://github.com/prettier/prettier/pull/5701
diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js
index 40f03656..9b7ba4b8 100644
--- a/src/language-markdown/printer-markdown.js
+++ b/src/language-markdown/printer-markdown.js
@@ -6,6 +6,7 @@ const pragma = require("./pragma");
const preprocess = require("./preprocess");
const {
builders: {
+ breakParent,
concat,
join,
line,
@@ -13,6 +14,7 @@ const {
markAsRoot,
hardline,
softline,
+ ifBreak,
fill,
align,
indent,
@@ -509,6 +511,7 @@ function printLine(path, value, options) {
}
function printTable(path, options, print) {
+ const hardlineWithoutBreakParent = hardline.parts[0];
const node = path.getValue();
const contents = []; // { [rowIndex: number]: { [columnIndex: number]: string } }
@@ -524,6 +527,7 @@ function printTable(path, options, print) {
contents.push(rowContents);
}, "children");
+ // Get the width of each column
const columnMaxWidths = contents.reduce(
(currentWidths, rowContents) =>
currentWidths.map((width, columnIndex) =>
@@ -531,28 +535,49 @@ function printTable(path, options, print) {
),
contents[0].map(() => 3) // minimum width = 3 (---, :--, :-:, --:)
);
-
- return join(hardline, [
+ const alignedTable = join(hardlineWithoutBreakParent, [
printRow(contents[0]),
printSeparator(),
- join(hardline, contents.slice(1).map(printRow))
+ join(
+ hardlineWithoutBreakParent,
+ contents.slice(1).map(rowContents => printRow(rowContents))
+ )
]);
- function printSeparator() {
+ if (options.proseWrap !== "never") {
+ return concat([breakParent, alignedTable]);
+ }
+
+ // Only if the --prose-wrap never is set and it exceeds the print width.
+ const compactTable = join(hardlineWithoutBreakParent, [
+ printRow(contents[0], /* isCompact */ true),
+ printSeparator(/* isCompact */ true),
+ join(
+ hardlineWithoutBreakParent,
+ contents
+ .slice(1)
+ .map(rowContents => printRow(rowContents, /* isCompact */ true))
+ )
+ ]);
+
+ return concat([breakParent, group(ifBreak(compactTable, alignedTable))]);
+
+ function printSeparator(isCompact) {
return concat([
"| ",
join(
" | ",
columnMaxWidths.map((width, index) => {
+ const spaces = isCompact ? 3 : width;
switch (node.align[index]) {
case "left":
- return ":" + "-".repeat(width - 1);
+ return ":" + "-".repeat(spaces - 1);
case "right":
- return "-".repeat(width - 1) + ":";
+ return "-".repeat(spaces - 1) + ":";
case "center":
- return ":" + "-".repeat(width - 2) + ":";
+ return ":" + "-".repeat(spaces - 2) + ":";
default:
- return "-".repeat(width);
+ return "-".repeat(spaces);
}
})
),
@@ -560,32 +585,36 @@ function printTable(path, options, print) {
]);
}
- function printRow(rowContents) {
+ function printRow(rowContents, isCompact) {
return concat([
"| ",
join(
" | ",
- rowContents.map((rowContent, columnIndex) => {
- switch (node.align[columnIndex]) {
- case "right":
- return alignRight(rowContent, columnMaxWidths[columnIndex]);
- case "center":
- return alignCenter(rowContent, columnMaxWidths[columnIndex]);
- default:
- return alignLeft(rowContent, columnMaxWidths[columnIndex]);
- }
- })
+ isCompact
+ ? rowContents
+ : rowContents.map((rowContent, columnIndex) => {
+ switch (node.align[columnIndex]) {
+ case "right":
+ return alignRight(rowContent, columnMaxWidths[columnIndex]);
+ case "center":
+ return alignCenter(rowContent, columnMaxWidths[columnIndex]);
+ default:
+ return alignLeft(rowContent, columnMaxWidths[columnIndex]);
+ }
+ })
),
" |"
]);
}
function alignLeft(text, width) {
- return concat([text, " ".repeat(width - privateUtil.getStringWidth(text))]);
+ const spaces = width - privateUtil.getStringWidth(text);
+ return concat([text, " ".repeat(spaces)]);
}
function alignRight(text, width) {
- return concat([" ".repeat(width - privateUtil.getStringWidth(text)), text]);
+ const spaces = width - privateUtil.getStringWidth(text);
+ return concat([" ".repeat(spaces), text]);
}
function alignCenter(text, width) {
diff --git a/tests/markdown_long_table/__snapshots__/jsfmt.spec.js.snap b/tests/markdown_long_table/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 00000000..1b3fe4c5
--- /dev/null
+++ b/tests/markdown_long_table/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,76 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`long-table.md 1`] = `
+====================================options=====================================
+parsers: ["markdown"]
+printWidth: 80
+ | printWidth
+=====================================input======================================
+| Property | Description | Type | Default |
+| -------- | ----------- | ---- | ------- |
+| bordered | Toggles rendering of the border around the list | boolean | false |
+| footer | List footer renderer | string\\|ReactNode | - |
+| grid | The grid type of list. You can set grid to something like {gutter: 16, column: 4} | object | - |
+| header | List header renderer | string\\|ReactNode | - |
+| itemLayout | The layout of list, default is \`horizontal\`, If a vertical list is desired, set the itemLayout property to \`vertical\` | string | - |
+| rowKey | Item's unique key, could be a string or function that returns a string | string\\|Function(record):string | \`key\` |
+| loading | Shows a loading indicator while the contents of the list are being fetched | boolean\\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false |
+| loadMore | Shows a load more content | string\\|ReactNode | - |
+| locale | i18n text including empty text | object | emptyText: 'No Data'
|
+| pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \\| object | false |
+| split | Toggles rendering of the split under the list item | boolean | true |
+=====================================output=====================================
+| Property | Description | Type | Default |
+| ---------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
+| bordered | Toggles rendering of the border around the list | boolean | false |
+| footer | List footer renderer | string\\|ReactNode | - |
+| grid | The grid type of list. You can set grid to something like {gutter: 16, column: 4} | object | - |
+| header | List header renderer | string\\|ReactNode | - |
+| itemLayout | The layout of list, default is \`horizontal\`, If a vertical list is desired, set the itemLayout property to \`vertical\` | string | - |
+| rowKey | Item's unique key, could be a string or function that returns a string | string\\|Function(record):string | \`key\` |
+| loading | Shows a loading indicator while the contents of the list are being fetched | boolean\\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false |
+| loadMore | Shows a load more content | string\\|ReactNode | - |
+| locale | i18n text including empty text | object | emptyText: 'No Data'
|
+| pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \\| object | false |
+| split | Toggles rendering of the split under the list item | boolean | true |
+
+================================================================================
+`;
+
+exports[`long-table.md 2`] = `
+====================================options=====================================
+parsers: ["markdown"]
+printWidth: 80
+proseWrap: "never"
+ | printWidth
+=====================================input======================================
+| Property | Description | Type | Default |
+| -------- | ----------- | ---- | ------- |
+| bordered | Toggles rendering of the border around the list | boolean | false |
+| footer | List footer renderer | string\\|ReactNode | - |
+| grid | The grid type of list. You can set grid to something like {gutter: 16, column: 4} | object | - |
+| header | List header renderer | string\\|ReactNode | - |
+| itemLayout | The layout of list, default is \`horizontal\`, If a vertical list is desired, set the itemLayout property to \`vertical\` | string | - |
+| rowKey | Item's unique key, could be a string or function that returns a string | string\\|Function(record):string | \`key\` |
+| loading | Shows a loading indicator while the contents of the list are being fetched | boolean\\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false |
+| loadMore | Shows a load more content | string\\|ReactNode | - |
+| locale | i18n text including empty text | object | emptyText: 'No Data'
|
+| pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \\| object | false |
+| split | Toggles rendering of the split under the list item | boolean | true |
+=====================================output=====================================
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| bordered | Toggles rendering of the border around the list | boolean | false |
+| footer | List footer renderer | string\\|ReactNode | - |
+| grid | The grid type of list. You can set grid to something like {gutter: 16, column: 4} | object | - |
+| header | List header renderer | string\\|ReactNode | - |
+| itemLayout | The layout of list, default is \`horizontal\`, If a vertical list is desired, set the itemLayout property to \`vertical\` | string | - |
+| rowKey | Item's unique key, could be a string or function that returns a string | string\\|Function(record):string | \`key\` |
+| loading | Shows a loading indicator while the contents of the list are being fetched | boolean\\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false |
+| loadMore | Shows a load more content | string\\|ReactNode | - |
+| locale | i18n text including empty text | object | emptyText: 'No Data'
|
+| pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \\| object | false |
+| split | Toggles rendering of the split under the list item | boolean | true |
+
+================================================================================
+`;
diff --git a/tests/markdown_long_table/jsfmt.spec.js b/tests/markdown_long_table/jsfmt.spec.js
new file mode 100644
index 00000000..e1c94789
--- /dev/null
+++ b/tests/markdown_long_table/jsfmt.spec.js
@@ -0,0 +1,2 @@
+run_spec(__dirname, ["markdown"]);
+run_spec(__dirname, ["markdown"], { proseWrap: "never" });
diff --git a/tests/markdown_long_table/long-table.md b/tests/markdown_long_table/long-table.md
new file mode 100644
index 00000000..57ff8ab2
--- /dev/null
+++ b/tests/markdown_long_table/long-table.md
@@ -0,0 +1,13 @@
+| Property | Description | Type | Default |
+| -------- | ----------- | ---- | ------- |
+| bordered | Toggles rendering of the border around the list | boolean | false |
+| footer | List footer renderer | string\|ReactNode | - |
+| grid | The grid type of list. You can set grid to something like {gutter: 16, column: 4} | object | - |
+| header | List header renderer | string\|ReactNode | - |
+| itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - |
+| rowKey | Item's unique key, could be a string or function that returns a string | string\|Function(record):string | `key` |
+| loading | Shows a loading indicator while the contents of the list are being fetched | boolean\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false |
+| loadMore | Shows a load more content | string\|ReactNode | - |
+| locale | i18n text including empty text | object | emptyText: 'No Data'
|
+| pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \| object | false |
+| split | Toggles rendering of the split under the list item | boolean | true |
\ No newline at end of file
diff --git a/tests/markdown_table/__snapshots__/jsfmt.spec.js.snap b/tests/markdown_table/__snapshots__/jsfmt.spec.js.snap
index e4eb22d7..aa3638a5 100644
--- a/tests/markdown_table/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/markdown_table/__snapshots__/jsfmt.spec.js.snap
@@ -134,3 +134,45 @@ proseWrap: "always"
================================================================================
`;
+
+exports[`table.md 1`] = `
+====================================options=====================================
+parsers: ["markdown"]
+printWidth: 80
+proseWrap: "always"
+ | printWidth
+=====================================input======================================
+- min-table
+
+ | Age | Time | Food | Gold | Requirement |
+ | ------------ | ----- | ---- | ---- | ----------------------- |
+ | Feudal Age | 02:10 | 500 | 0 | Dark Age building x 2 |
+ | Castle Age | 02:40 | 800 | 200 |- |
+ | Imperial Age | 03:30 | 1000 | 800 | Castle Age building x 2 |
+- big-table
+
+ |学号|姓名|分数|
+ |-|-|-|
+ |小明|男|75|
+ |小红|女|79|
+ |小陆|男|92|
+
+=====================================output=====================================
+- min-table
+
+ | Age | Time | Food | Gold | Requirement |
+ | ------------ | ----- | ---- | ---- | ----------------------- |
+ | Feudal Age | 02:10 | 500 | 0 | Dark Age building x 2 |
+ | Castle Age | 02:40 | 800 | 200 | - |
+ | Imperial Age | 03:30 | 1000 | 800 | Castle Age building x 2 |
+
+- big-table
+
+ | 学号 | 姓名 | 分数 |
+ | ---- | ---- | ---- |
+ | 小明 | 男 | 75 |
+ | 小红 | 女 | 79 |
+ | 小陆 | 男 | 92 |
+
+================================================================================
+`;
diff --git a/tests/markdown_table/table.md b/tests/markdown_table/table.md
new file mode 100644
index 00000000..2096adf1
--- /dev/null
+++ b/tests/markdown_table/table.md
@@ -0,0 +1,14 @@
+- min-table
+
+ | Age | Time | Food | Gold | Requirement |
+ | ------------ | ----- | ---- | ---- | ----------------------- |
+ | Feudal Age | 02:10 | 500 | 0 | Dark Age building x 2 |
+ | Castle Age | 02:40 | 800 | 200 |- |
+ | Imperial Age | 03:30 | 1000 | 800 | Castle Age building x 2 |
+- big-table
+
+ |学号|姓名|分数|
+ |-|-|-|
+ |小明|男|75|
+ |小红|女|79|
+ |小陆|男|92|