Refactor: Simplify markdown table print (#9660)
This commit is contained in:
1 parent
dc541cc9b9
commit
ef6a2c5f8a
1 file changed
+43
-72
@@ -41,6 +41,10 @@ const {
|
||||
isAutolink,
|
||||
} = require("./utils");
|
||||
|
||||
/**
|
||||
* @typedef {import("../document").Doc} Doc
|
||||
*/
|
||||
|
||||
const TRAILING_HARDLINE_NODES = new Set(["importExport"]);
|
||||
const SINGLE_LINE_NODE_TYPES = ["heading", "tableCell", "link", "wikiLink"];
|
||||
const SIBLING_NODE_TYPES = new Set([
|
||||
@@ -577,37 +581,34 @@ function printTable(path, options, print) {
|
||||
const hardlineWithoutBreakParent = hardline.parts[0];
|
||||
const node = path.getValue();
|
||||
|
||||
// { [rowIndex: number]: { [columnIndex: number]: string } }
|
||||
const columnMaxWidths = [];
|
||||
// { [rowIndex: number]: { [columnIndex: number]: {text: string, width: number} } }
|
||||
const contents = path.map(
|
||||
(rowPath) =>
|
||||
rowPath.map(
|
||||
(cellPath) => printDocToString(cellPath.call(print), options).formatted,
|
||||
"children"
|
||||
),
|
||||
rowPath.map((cellPath, columnIndex) => {
|
||||
const text = printDocToString(cellPath.call(print), options).formatted;
|
||||
const width = getStringWidth(text);
|
||||
columnMaxWidths[columnIndex] = Math.max(
|
||||
columnMaxWidths[columnIndex] || 3, // minimum width = 3 (---, :--, :-:, --:)
|
||||
width
|
||||
);
|
||||
return { text, width };
|
||||
}, "children"),
|
||||
"children"
|
||||
);
|
||||
|
||||
// Get the width of each column
|
||||
const columnMaxWidths = contents.reduce(
|
||||
(currentWidths, rowContents) =>
|
||||
currentWidths.map((width, columnIndex) =>
|
||||
Math.max(width, getStringWidth(rowContents[columnIndex]))
|
||||
),
|
||||
contents[0].map(() => 3) // minimum width = 3 (---, :--, :-:, --:)
|
||||
);
|
||||
const alignedTable = printTableContents(/* isCompact */ false);
|
||||
|
||||
if (options.proseWrap !== "never") {
|
||||
return concat([breakParent, alignedTable]);
|
||||
}
|
||||
|
||||
// Only if the --prose-wrap never is set and it exceeds the print width.
|
||||
const compactTable = printTableContents(/* isCompact */ true);
|
||||
|
||||
return concat([breakParent, group(ifBreak(compactTable, alignedTable))]);
|
||||
|
||||
function printTableContents(isCompact) {
|
||||
const parts = [printRow(contents[0], isCompact), printSeparator(isCompact)];
|
||||
/** @type{Doc[]} */
|
||||
const parts = [printRow(contents[0], isCompact), printAlign(isCompact)];
|
||||
if (contents.length > 1) {
|
||||
parts.push(
|
||||
join(
|
||||
@@ -621,66 +622,36 @@ function printTable(path, options, print) {
|
||||
return join(hardlineWithoutBreakParent, parts);
|
||||
}
|
||||
|
||||
function printSeparator(isCompact) {
|
||||
return concat([
|
||||
"| ",
|
||||
join(
|
||||
" | ",
|
||||
columnMaxWidths.map((width, index) => {
|
||||
const spaces = isCompact ? 3 : width;
|
||||
switch (node.align[index]) {
|
||||
case "left":
|
||||
return ":" + "-".repeat(spaces - 1);
|
||||
case "right":
|
||||
return "-".repeat(spaces - 1) + ":";
|
||||
case "center":
|
||||
return ":" + "-".repeat(spaces - 2) + ":";
|
||||
default:
|
||||
return "-".repeat(spaces);
|
||||
}
|
||||
})
|
||||
),
|
||||
" |",
|
||||
]);
|
||||
function printAlign(isCompact) {
|
||||
const align = columnMaxWidths.map((width, index) => {
|
||||
const align = node.align[index];
|
||||
const first = align === "center" || align === "left" ? ":" : "-";
|
||||
const last = align === "center" || align === "right" ? ":" : "-";
|
||||
const middle = isCompact ? "-" : "-".repeat(width - 2);
|
||||
return `${first}${middle}${last}`;
|
||||
});
|
||||
|
||||
return `| ${align.join(" | ")} |`;
|
||||
}
|
||||
|
||||
function printRow(rowContents, isCompact) {
|
||||
return concat([
|
||||
"| ",
|
||||
join(
|
||||
" | ",
|
||||
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]);
|
||||
}
|
||||
})
|
||||
),
|
||||
" |",
|
||||
]);
|
||||
}
|
||||
const columns = rowContents.map(({ text, width }, columnIndex) => {
|
||||
if (isCompact) {
|
||||
return text;
|
||||
}
|
||||
const spaces = columnMaxWidths[columnIndex] - width;
|
||||
const align = node.align[columnIndex];
|
||||
let before = 0;
|
||||
if (align === "right") {
|
||||
before = spaces;
|
||||
} else if (align === "center") {
|
||||
before = Math.floor(spaces / 2);
|
||||
}
|
||||
const after = spaces - before;
|
||||
return `${" ".repeat(before)}${text}${" ".repeat(after)}`;
|
||||
});
|
||||
|
||||
function alignLeft(text, width) {
|
||||
const spaces = width - getStringWidth(text);
|
||||
return concat([text, " ".repeat(spaces)]);
|
||||
}
|
||||
|
||||
function alignRight(text, width) {
|
||||
const spaces = width - getStringWidth(text);
|
||||
return concat([" ".repeat(spaces), text]);
|
||||
}
|
||||
|
||||
function alignCenter(text, width) {
|
||||
const spaces = width - getStringWidth(text);
|
||||
const left = Math.floor(spaces / 2);
|
||||
const right = spaces - left;
|
||||
return concat([" ".repeat(left), text, " ".repeat(right)]);
|
||||
return `| ${columns.join(" | ")} |`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user