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 { 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), }) ] };