src/language-markdown/printer-markdown.js/printSeparator
function printTable(path, options, print) {
  const hardlineWithoutBreakParent = hardline.parts[0];
  const node = path.getValue();
  const contents = []; // { [rowIndex: number]: { [columnIndex: number]: string } }

  path.map((rowPath) => {
    const rowContents = [];

    rowPath.map((cellPath) => {
      rowContents.push(
        printDocToString(cellPath.call(print), options).formatted
      );
    }, "children");

    contents.push(rowContents);
  }, "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 = join(hardlineWithoutBreakParent, [
    printRow(contents[0]),
    printSeparator(),
    join(
      hardlineWithoutBreakParent,
      contents.slice(1).map((rowContents) => printRow(rowContents))
    ),
  ]);

  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(spaces - 1);
            case "right":
              return "-".repeat(spaces - 1) + ":";
            case "center":
              return ":" + "-".repeat(spaces - 2) + ":";
            default:
              return "-".repeat(spaces);
          }
        })
      ),
      " |",
    ]);
  }

  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]);
              }
            })
      ),
      " |",
    ]);
  }

  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)]);
  }
}