remarkFileLinksPlugin.ts1.5 KBView on GitHub import type { Parent, PhrasingContent, Root, Text } from 'mdast';
import { visit } from 'unist-util-visit';
const FILE_LINK_REGEX = /\[\[doc:([0-9a-fA-F-]{36})(?:\|([^\]]+))?\]\]/g;
export function remarkFileLinksPlugin() {
return (tree: Root) => {
visit(tree, 'text', (node: Text, index: number | undefined, parent: Parent | undefined) => {
if (index === undefined || !parent) return;
const value = node.value;
if (!value.includes('[[doc:')) return;
const newNodes: (Text | object)[] = [];
let lastIndex = 0;
let match: RegExpExecArray | null;
const regex = new RegExp(FILE_LINK_REGEX.source, 'g');
while ((match = regex.exec(value)) !== null) {
const matchStart = match.index;
const matchEnd = match.index + match[0].length;
if (matchStart > lastIndex) {
newNodes.push({ type: 'text', value: value.slice(lastIndex, matchStart) } as Text);
}
newNodes.push({
type: 'fileLink',
data: {
hName: 'file-link',
hProperties: {
'data-document-id': match[1],
},
},
});
lastIndex = matchEnd;
}
if (lastIndex < value.length) {
newNodes.push({ type: 'text', value: value.slice(lastIndex) } as Text);
}
if (newNodes.length > 1 || (newNodes.length === 1 && (newNodes[0] as Text).type !== 'text')) {
parent.children.splice(index, 1, ...(newNodes as PhrasingContent[]));
return index + newNodes.length;
}
});
};
}