UNPKG

aubade

Version:

filesystem-based content processor

73 lines (72 loc) 2.98 kB
import { matter } from '../artisan/index.js'; import { uhi } from '../utils.js'; export function parse(source) { const match = /---\r?\n([\s\S]+?)\r?\n---/.exec(source); if (!match) return { body: source }; const crude = source.slice(match.index + match[0].length); const memory = matter(match[1].trim()); const stuffed = inject(crude, memory); return { // @TODO: return AST (after implementing `markdown()`) body: stuffed.trim(), frontmatter: Object.assign(memory, { /** estimated reading time */ get estimate() { const paragraphs = stuffed.split('\n').filter((p) => !!p && !/^[!*]/.test(p)); const words = paragraphs.reduce((total, line) => { if (/^[\t\s]*<.+>/.test(line.trim())) return total + 1; const accumulated = line.split(' ').filter((w) => !!w && /\w|\d/.test(w) && w.length > 1); return total + accumulated.length; }, 0); const images = stuffed.match(/!\[.+\]\(.+\)/g); const total = words + (images || []).length * 12; return Math.round(total / 240) || 1; }, /** table of contents */ get table() { const table = []; for (const line of stuffed.replace(/<!--[\s\S]+?-->/g, '').split('\n')) { const match = line.trim().match(/^(#{2,4}) (.+)/); if (!match) continue; const [, hashes, title] = match; const [delimited] = title.match(/\$\(.*?\)/) || ['']; table.push({ id: uhi(delimited.slice(2, -1) || title), title: title.replace(delimited, delimited.slice(2, -1)), level: hashes.length, }); } let parents = ['', '']; for (let i = 0; i < table.length; i++) { const { id, level } = table[i]; if (level === 2) parents = [id]; if (level === 3) parents = [parents[0], id]; if (level === 4) parents[2] = id; table[i].id = parents.filter((p) => p).join('-'); } return table; }, }), }; } function inject(source, metadata) { const plane = compress(metadata); return source.replace(/!{(.+)}/g, (s, c) => (c && plane[c]) || s); } function compress(metadata, parent = '') { const memo = {}; const prefix = parent ? `${parent}:` : ''; for (const [k, v] of Object.entries(metadata)) { if (typeof v !== 'object') memo[prefix + k] = v; else Object.assign(memo, compress(v, k)); } return memo; }