UNPKG

@thi.ng/markdown-table

Version:

Markdown table formatter/generator with support for column alignments

79 lines (78 loc) 2.33 kB
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 };