58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
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,
|
|
})
|
|
]
|
|
};
|