```\s?(?.+)?)|(###\s?(? .+))|(##\s?(?
.+))|(#\s?(?
.+))|(\*\s?(?
.+))|(>\s?(? .+))|(?(.+)?))$/; export function html(file, options) { const tokens = file.contents .toString("utf8") .split("\n") .map((line) => GMI_REGEX.exec(line).groups); if (options.body) return body(tokens, options); return ` ${head( Object.assign(options, { title: tokens[0].h1, charset: "utf-8", }) )} ${body(tokens, options)} `; } export const BASE_CSS = "p,a,pre,h1,h2,h3,ul,blockquote,img,audio,video{display:block;max-width:100%;margin:0;padding:0;overflow-wrap:anywhere;}"; export function head(options) { return ` ${ options.css !== "" ? `` : "" } ${options.css !== "" ? `` : ""} ${options.title} ${ !options.description ? "" : `` }${ !options.canonical ? "" : `` } `; } function line( { text, href, title, pre, alt, h1, h2, h3, li, quote }, { image, audio, video, css } = {} ) { if (text) return `${escape(text)}
`; const matchesExt = (url, exts) => exts.some((ext) => new RegExp(`\.${ext}$`).test(url)); if (href) { const titleProp = title ? ` title="${title}"` : ""; if (image && matchesExt(href, image)) { return ``; } if (audio && matchesExt(href, audio)) { if (css === "") { return ``; } return ``; } if (video && matchesExt(href, video)) return ``; if (css === "") { return `
${title ? escape(title) : href}
`; } return `${title ? escape(title) : href}`; } if (h1) return `${escape(h1)}
`; if (h2) return `${escape(h2)}
`; if (h3) return `${escape(h3)}
`; if (li) return `${escape(li)} `; if (quote) return `${escape(quote)}`; return ``; } export function body(tokens, options) { let lines = []; let cursor = tokens.shift(); while (tokens.length) { if (cursor.pre) { lines.push(`
`); const closing = tokens.findIndex((token) => token.pre); lines = lines.concat(tokens.slice(0, closing).map(({ text }) => text)); lines.push(""); tokens = tokens.slice(closing + 1); } else if (cursor.li) { lines.push(``); const closing = tokens.findIndex((token) => !token.li); lines = lines .concat([line(cursor)]) .concat(tokens.slice(0, closing).map(line)); lines.push("
"); tokens = tokens.slice(closing); } else { lines.push(line(cursor, options)); } cursor = tokens.shift(); } return lines.join("\n"); } export const GMI_EXT = /\.gmi$/; export default (options) => (file, cb) => { if (!GMI_EXT.test(file.path)) return cb(null); file.contents = Buffer.from(html(file, options)); file.path = file.path.replace(GMI_EXT, ".html"); if (options.verbose) console.log(file.path); return cb(null, file); };