@thi.ng/transclude
Version:
Extensible functional template engine for text document generation, incl. various high-level Markdown features
49 lines (48 loc) • 1.39 kB
JavaScript
import { repeat } from "@thi.ng/strings/repeat";
import { slugifyGH } from "@thi.ng/strings/slugify";
import { split } from "@thi.ng/strings/split";
import { comp } from "@thi.ng/transducers/comp";
import { filter } from "@thi.ng/transducers/filter";
import { map } from "@thi.ng/transducers/map";
import { str } from "@thi.ng/transducers/str";
import { transduce } from "@thi.ng/transducers/transduce";
const image = (url, alt = "") => ``;
const link = (title, href) => `[${title}](${href})`;
const list = (items, eol = "\n") => transduce(
map((x) => `- ${x}`),
str(eol),
items
);
const toc = (opts = {}) => ({ src, eol }) => {
const {
min = 2,
max = 4,
match = /<!-- toc -->/i,
disable = /<!-- notoc -->/i,
title
} = opts;
const isHeading = new RegExp(`^#{${min},${max}}\\s`);
const reHeading = new RegExp(`^(#{${min},${max}})\\s(.+)`);
const toc2 = transduce(
comp(
filter((line) => isHeading.test(line) && !disable.test(line)),
map((hd) => {
const [_, level, title2] = reHeading.exec(hd);
const indent = repeat(
" ",
Math.max(0, level.length - min)
);
return `${indent}- ${link(title2, `#${slugifyGH(title2)}`)}`;
})
),
str(eol),
split(src)
);
return src.replace(match, title ? title + toc2 : toc2);
};
export {
image,
link,
list,
toc
};