Open1

Markdown風のテーブルtemplate literalで実装する

suinsuin
export type Table = ReadonlyArray<Row>;
export type Row = ReadonlyArray<string> &
  { readonly [K in number | string]?: string };

export default function table(
  strings: TemplateStringsArray,
  ...placeholders: any[]
): Table {
  if (strings.length > 1 || placeholders.length > 0) {
    throw new Error("This tagged template can't handle placeholders");
  }
  const [string] = strings;
  if (typeof string !== "string") {
    throw new Error("Given value is not a type string");
  }
  const lines = string
    .split("\n")
    .map((line) => line.trim())
    .filter((line) => line.length > 0)
    .map((row) =>
      row
        .split("|")
        .map((column) => column.trim())
        .filter((column) => column.length > 0)
    );
  if (lines.length < 3) {
    throw new Error("The given string must be valid Markdown table");
  }
  const [names, , ...records] = lines;
  return records.map((record) =>
    record.reduce(
      (acc, value, index) => Object.assign(acc, { [names![index]!]: value }),
      record as any
    )
  );
}