Vault.MCP / frontend /src /lib /wikilink.ts
bigwolfe
Document viewer done
61aec16
/**
* T072: Extract wikilinks from markdown text
* Matches [[link text]] pattern
*/
export function extractWikilinks(text: string): string[] {
const pattern = /\[\[([^\]]+)\]\]/g;
const matches: string[] = [];
let match;
while ((match = pattern.exec(text)) !== null) {
matches.push(match[1]);
}
return matches;
}
/**
* T073: Normalize text to a URL-safe slug
* - Lowercase
* - Replace spaces and underscores with dashes
* - Strip non-alphanumeric except dashes
*/
export function normalizeSlug(text: string): string {
return text
.toLowerCase()
.replace(/[\s_]+/g, '-')
.replace(/[^a-z0-9-]/g, '')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
}
/**
* Parse wikilink syntax in markdown text
* Returns array of { text, linkText } objects
*/
export function parseWikilinks(text: string): Array<{ text: string; linkText: string | null }> {
const parts: Array<{ text: string; linkText: string | null }> = [];
const pattern = /\[\[([^\]]+)\]\]/g;
let lastIndex = 0;
let match;
while ((match = pattern.exec(text)) !== null) {
// Add text before the wikilink
if (match.index > lastIndex) {
parts.push({
text: text.slice(lastIndex, match.index),
linkText: null,
});
}
// Add the wikilink
parts.push({
text: match[0],
linkText: match[1],
});
lastIndex = pattern.lastIndex;
}
// Add remaining text
if (lastIndex < text.length) {
parts.push({
text: text.slice(lastIndex),
linkText: null,
});
}
return parts;
}
/**
* Convert wikilink text to a probable note path
* Adds .md extension and normalizes
*/
export function wikilinkToPath(linkText: string): string {
const slug = normalizeSlug(linkText);
return `${slug}.md`;
}