73 lines
3.6 KiB
TypeScript
73 lines
3.6 KiB
TypeScript
import type { Element, MarkdownConfig } from '@lezer/markdown';
|
|
import { styleTags, tags } from '@lezer/highlight';
|
|
|
|
export const wikilink: MarkdownConfig = {
|
|
defineNodes: [
|
|
'Wikilink',
|
|
'WikilinkMeta',
|
|
'WikilinkHref',
|
|
'WikilinkTitle',
|
|
],
|
|
parseInline: [{
|
|
name: 'Wikilink',
|
|
before: 'Link',
|
|
parse(cx, next, pos)
|
|
{
|
|
// 91 == '['
|
|
if (next !== 91 || cx.slice(pos, pos + 1).charCodeAt(0) !== 91) return -1;
|
|
|
|
const match = /!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/.exec(cx.slice(pos, cx.end));
|
|
if(!match) return -1;
|
|
|
|
const start = pos, children: Element[] = [], end = start + match[0].length;
|
|
|
|
children.push(cx.elt('WikilinkMeta', start, start + 2));
|
|
|
|
if(match[1] && !match[2] && !match[3]) //Link only
|
|
{
|
|
children.push(cx.elt('WikilinkTitle', start + 2, end - 2));
|
|
}
|
|
else if(!match[1] && match[2] && match[3]) //Hash and title
|
|
{
|
|
children.push(cx.elt('WikilinkHref', start + 2, start + 2 + match[2].length));
|
|
children.push(cx.elt('WikilinkMeta', start + 2 + match[2].length, start + 2 + match[2].length + 1));
|
|
children.push(cx.elt('WikilinkTitle', start + 2 + match[2].length + 1, start + 2 + match[2].length + match[3].length));
|
|
}
|
|
else if(!match[1] && !match[2] && match[3]) //Hash only
|
|
{
|
|
children.push(cx.elt('WikilinkTitle', start + 2, end - 2));
|
|
}
|
|
else if(match[1] && match[2] && !match[3]) //Link and hash
|
|
{
|
|
children.push(cx.elt('WikilinkHref', start + 2, start + 2 + match[1].length));
|
|
children.push(cx.elt('WikilinkTitle', start + 2 + match[1].length, start + 2 + match[1].length + match[2].length));
|
|
}
|
|
else if(match[1] && !match[2] && match[3]) //Link and title
|
|
{
|
|
children.push(cx.elt('WikilinkHref', start + 2, start + 2 + match[1].length));
|
|
children.push(cx.elt('WikilinkMeta', start + 2 + match[1].length, start + 2 + match[1].length + 1));
|
|
children.push(cx.elt('WikilinkTitle', start + 2 + match[1].length + 1, start + 2 + match[1].length + match[3].length));
|
|
}
|
|
else if(match[1] && match[2] && match[3]) //Link, hash and title
|
|
{
|
|
//console.log(cx.slice(pos, end), '/', cx.slice(start + 2, start + 2 + match[1].length + match[2].length), '/', cx.slice(start + 2 + match[1].length + match[2].length, start + 2 + match[1].length + match[2].length + 1), cx.slice(start + 2 + match[1].length + match[2].length + 1, start + 2 + match[1].length + match[2].length + match[3].length))
|
|
children.push(cx.elt('WikilinkHref', start + 2, start + 2 + match[1].length + match[2].length));
|
|
children.push(cx.elt('WikilinkMeta', start + 2 + match[1].length + match[2].length, start + 2 + match[1].length + match[2].length + 1));
|
|
children.push(cx.elt('WikilinkTitle', start + 2 + match[1].length + match[2].length + 1, start + 2 + match[1].length + match[2].length + match[3].length));
|
|
}
|
|
|
|
children.push(cx.elt('WikilinkMeta', end - 2, end));
|
|
|
|
return cx.addElement(cx.elt('Wikilink', start, end, children));
|
|
},
|
|
}],
|
|
props: [
|
|
styleTags({
|
|
'Wikilink': tags.special(tags.content),
|
|
'WikilinkMeta': tags.meta,
|
|
'WikilinkHref': tags.link,
|
|
'WikilinkTitle': tags.special(tags.link),
|
|
})
|
|
]
|
|
};
|