UNPKG

@tanstack/markdown

Version:

A tiny, fast, deterministic Markdown renderer for blogs and documentation.

51 lines (50 loc) 1.79 kB
export function commentComponentsExtension(options = {}) { return { name: 'comment-components', parseBlock: context => parseCommentComponentBlock(context, options), }; } export function parseCommentComponentBlock(context, options = {}) { const line = context.lines[context.index] ?? ''; const start = parseComponentComment(line); if (!start) return undefined; let body; let consumed = 1; if (start.block) { const end = new RegExp(`^ {0,3}<!--\\s*::end:${start.name}\\s*-->\\s*$`, 'i'); for (let cursor = context.index + 1; cursor < context.lines.length; cursor++) { if (end.test(context.lines[cursor])) { body = context.lines.slice(context.index + 1, cursor).join('\n'); consumed = cursor - context.index + 1; break; } } } context.consume(consumed); const node = { type: 'component', name: start.name, attributes: start.attributes, children: body === undefined ? [] : context.parseBlocks(body), }; return options.transformComponent?.(node) ?? node; } export function parseComponentComment(line) { const match = line.match(/^ {0,3}<!--\s*::(start:)?([A-Za-z][\w-]*)(.*?)\s*-->\s*$/); if (!match) return undefined; return { block: Boolean(match[1]), name: match[2].toLowerCase(), attributes: parseAttributes(match[3] ?? ''), }; } export function parseAttributes(value) { const attrs = Object.create(null); const regex = /([A-Za-z_][\w:-]*)(?:=(?:"([^"]*)"|'([^']*)'|([^\s"']+)))?/g; for (const match of value.matchAll(regex)) { attrs[match[1]] = match[2] ?? match[3] ?? match[4] ?? 'true'; } return attrs; }