UNPKG

@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
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 = "") => `![${alt}](${url})`; 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 };