import type { MarkdownConfig } from '@lezer/markdown'; import { styleTags, tags } from '@lezer/highlight'; export const callout: MarkdownConfig = { defineNodes: [ 'CalloutBlock', 'CalloutMarker', 'CalloutMark', 'CalloutType', 'CalloutTitle', 'CalloutLine', 'CalloutContent', ], parseBlock: [{ name: 'Callout', before: 'Blockquote', parse(cx, line) { const match = /^>\s*\[!(\w+)\](?:\s+(.*))?/.exec(line.text); if (!match || !match[1]) return false; //No match const start = cx.lineStart, children = []; const quoteEnd = start + line.text.indexOf('[!'); const typeStart = quoteEnd + 2; const typeEnd = typeStart + match[1].length; const bracketEnd = typeEnd + 1; children.push(cx.elt('CalloutMarker', start, bracketEnd, [ cx.elt('CalloutMark', start, quoteEnd), cx.elt('CalloutType', typeStart, typeEnd) ])); if(match[2]) children.push(cx.elt('CalloutTitle', bracketEnd + 1, start + line.text.length)); while (cx.nextLine() && line.text.startsWith('>')) { const pos = line.text.substring(1).search(/\S/) + 1; children.push(cx.elt('CalloutLine', cx.lineStart, cx.lineStart + line.text.length, [ cx.elt('CalloutMark', cx.lineStart, cx.lineStart + pos), cx.elt('CalloutContent', cx.lineStart + pos, cx.lineStart + line.text.length), ])) } cx.addElement(cx.elt('CalloutBlock', start, cx.lineStart - 1, children)); return true; } }], props: [ styleTags({ 'CalloutBlock': tags.special(tags.quote), 'CalloutMarker': tags.meta, 'CalloutMark': tags.meta, 'CalloutType': tags.keyword, 'CalloutTitle': tags.heading, 'CalloutLine': tags.content, 'CalloutContent': tags.content, }) ] };