UNPKG

aubade

Version:

filesystem-based content processor

72 lines (71 loc) 2.2 kB
export function heading({ cursor, stack }) { const match = cursor.locate(/\s/); if (!/^#{1,6}$/.test(match)) return null; const { length: level } = match; const title = cursor.locate(/\n|$/).trim(); if (!title.length) return null; const sibling = stack.find('parent:heading', (token) => token.meta.level === level); if (sibling) stack.remove(sibling); const parent = stack.find('parent:heading', (token) => token.meta.level === level - 1); const id = `${parent?.attr.id || ''}-${title.toLowerCase()}` .replace(/[\s\][!"#$%&'()*+,./:;<=>?@\\^_`{|}~-]+/g, '-') .replace(/^-+|-+$|(?<=-)-+/g, ''); return stack.push({ type: 'parent:heading', text: title, attr: { id }, meta: { level }, children: [], }); } export function html({ cursor, compose }) { const open = cursor.read(1); if (open !== '<') return null; const tag = cursor.locate(/\s|>/); if (!tag.length) return null; cursor.eat('>'); // TODO: handle elements without closing tags compose; // recursive call to parse the inner HTML const html = cursor.locate(new RegExp(`</${tag}>`)); if (!html.length) return null; cursor.eat(`</${tag}>`); return { type: 'parent:html', text: html, attr: {}, children: [], }; } export function paragraph({ cursor, stack }) { const text = cursor.locate(/\n|$/).trim(); cursor.eat('\n'); // eat the newline character const last = stack.peek(); if (last?.type === 'parent:paragraph') { last.text += '\n' + text; return last; } return stack.push({ type: 'parent:paragraph', text: text, children: [], }); } export function quote({ cursor, stack, compose }) { const match = cursor.eat('>'); if (!match) return null; const body = cursor.locate(/\n|$/).trim(); const { children } = compose(body); const last = stack.peek(); if (last?.type === 'parent:quote') { last.children.push(...children); return last; } return stack.push({ type: 'parent:quote', children }); }