@thi.ng/markdown-table
Version:
Markdown table formatter/generator with support for column alignments
79 lines (78 loc) • 2.33 kB
JavaScript
import { isString } from "@thi.ng/checks/is-string";
import { juxt } from "@thi.ng/compose/juxt";
import { assert } from "@thi.ng/errors/assert";
import { center } from "@thi.ng/strings/center";
import { padLeft } from "@thi.ng/strings/pad-left";
import { padRight } from "@thi.ng/strings/pad-right";
import { repeat } from "@thi.ng/strings/repeat";
import { wrap } from "@thi.ng/strings/wrap";
import { comp } from "@thi.ng/transducers/comp";
import { last } from "@thi.ng/transducers/last";
import { map } from "@thi.ng/transducers/map";
import { max } from "@thi.ng/transducers/max";
import { multiplex } from "@thi.ng/transducers/multiplex";
import { range } from "@thi.ng/transducers/range";
import { repeat as $repeat } from "@thi.ng/transducers/repeat";
import { repeatedly } from "@thi.ng/transducers/repeatedly";
import { scan } from "@thi.ng/transducers/scan";
import { transduce } from "@thi.ng/transducers/transduce";
const PADS = {
c: center,
l: padRight,
r: padLeft
};
const SEPS = {
c: (x) => `:${repeat("-", x)}:`,
l: (x) => `:${repeat("-", x + 1)}`,
r: (x) => `${repeat("-", x + 1)}:`
};
const table = (header, rows, opts = {}) => {
const numColumns = header.length;
const align = opts.align || [...$repeat("l", numColumns)];
assert(align.length === numColumns, `invalid/missing column alignments`);
opts.bold && (header = header.map(wrap("**")));
const body = [header, ...rows];
const widths = transduce(
multiplex(
...[
...repeatedly(
(i) => comp(
map(
(row) => row[i] != null ? String(row[i]).length : 0
),
scan(max())
),
numColumns
)
]
),
last(),
body
);
const pads = widths.map((w, i) => PADS[align[i]](w));
const colIDs = [...range(numColumns)];
const result = body.map(
(row) => colIDs.map((i) => `| ${pads[i](__str(row[i]))} `).join("") + "|"
);
result.splice(
1,
0,
widths.map((w, i) => `|${SEPS[align[i]](w)}`).join("") + "|"
);
return result.join("\n");
};
const tableKeys = (headers, keys, items, opts) => table(
headers,
map(
juxt(
...keys.map((k) => isString(k) ? (x) => __str(x[k]) : k)
),
items
),
opts
);
const __str = (x) => x != null ? String(x) : "";
export {
table,
tableKeys
};