Files

54 lines
1.3 KiB
TypeScript

import { EditorState } from '@codemirror/state';
import { resolveReferenceFromLink } from '../referenceLinksStateField';
import { SyntaxNodeRef, Tree } from '@lezer/common';
enum MatchedUrlType {
Footnote,
Link,
}
type MatchedUrl = {
type: MatchedUrlType;
url: string;
label?: string;
};
const getUrlAtPosition = (pos: number, tree: Tree, state: EditorState): MatchedUrl|null => {
const nodeText = (node: SyntaxNodeRef) => {
return state.doc.sliceString(node.from, node.to);
};
let iterator = tree.resolveStack(pos);
while (true) {
if (iterator.node.name === 'Link') {
const urlNode = iterator.node.getChild('URL');
if (urlNode) {
return { type: MatchedUrlType.Link, url: nodeText(urlNode) };
}
const fullLinkText = nodeText(iterator.node);
const referenceLink = resolveReferenceFromLink(fullLinkText, state);
if (referenceLink) {
const isFootnote = fullLinkText.match(/^\[\^\d+\]$/);
if (isFootnote) {
return { type: MatchedUrlType.Footnote, url: fullLinkText, label: referenceLink };
} else {
return { type: MatchedUrlType.Link, url: referenceLink };
}
}
} else if (iterator.node.name === 'URL') {
return { type: MatchedUrlType.Link, url: nodeText(iterator.node) };
}
if (!iterator.next) {
break;
} else {
iterator = iterator.next;
}
}
return null;
};
export default getUrlAtPosition;