refactoring of cmaps, widgets, etc.

This commit is contained in:
2026-09-02 16:06:26 +02:00
parent 38f255c1a4
commit f0562a06cc
52 changed files with 3626 additions and 2642 deletions
+28 -9
View File
@@ -182,6 +182,14 @@ function positionIsProtected(start, end, ranges) {
return false;
}
/** Encode the initial WikiWord letter so a later render pass cannot link it. */
function literalWikiWord(namespace, wikiWord) {
const characters = Array.from(wikiWord);
const initial = `&#${characters[0].codePointAt(0)};`;
const prefix = namespace ? `${namespace}:` : "";
return `${prefix}${initial}${characters.slice(1).join("")}`;
}
/**
* goal : Rewrite namespaced Markdown targets to internal hash routes.
* pre : markdown is source text; fenced and indented code must remain untouched.
@@ -219,15 +227,18 @@ function expandNamespacedMarkdownLinks(markdown) {
/**
* goal : Expand classic WikiWords to temporary Markdown links.
* pre : pages, pageAliases and conceptMaps are current catalogues.
* post : Code, Todo markers, URLs and existing Markdown links remain unchanged.
* result : Render-only Markdown with WikiWord links.
* post : Code, Todo markers, URLs and existing Markdown links remain unchanged;
* an exclamation mark directly before a WikiWord suppresses its link.
* result : Render-only Markdown with WikiWord links. Literal WikiWords contain
* an equivalent HTML character reference and remain literal when the
* transformation is applied again.
*/
function expandWikiMentions(markdown, pages, pageAliases, conceptMaps, currentSlug = null) {
const aliases = pageMentionMap(pages, pageAliases, currentSlug);
const lines = String(markdown || "").split("\n");
const result = [];
let fence = null;
const wikiWordPattern = /(?<![\p{L}\p{N}._-])(?:([\p{L}\p{N}._-]+):)?((?:\p{Lu}\p{Ll}+){2,})(?![\p{L}\p{N}._-])/gu;
const wikiWordPattern = /(?<![\p{L}\p{N}._-])(!?)(?:([\p{L}\p{N}._-]+):)?((?:\p{Lu}\p{Ll}+){2,})(?![\p{L}\p{N}_-]|\.[\p{L}\p{N}_-])/gu;
for (const line of lines) {
const fenceMatch = line.match(/^\s*(```+|~~~+)/);
@@ -250,12 +261,20 @@ function expandWikiMentions(markdown, pages, pageAliases, conceptMaps, currentSl
const start = match.index;
const end = start + match[0].length;
if (positionIsProtected(start, end, protectedRanges)) continue;
const namespace = match[1] || "";
if (match[1] === "!") {
replacements.push({
start,
end,
text: literalWikiWord(match[2] || "", match[3])
});
continue;
}
const namespace = match[2] || "";
if (namespace.toLocaleLowerCase() === "cmap") {
const conceptMap = cmapMentionTarget(match[2], conceptMaps);
const conceptMap = cmapMentionTarget(match[3], conceptMaps);
if (conceptMap) replacements.push({ start, end, conceptMap });
} else {
const page = wikiWordTarget(match[2], aliases, namespace);
const page = wikiWordTarget(match[3], aliases, namespace);
if (page) replacements.push({ start, end, page });
}
}
@@ -263,10 +282,10 @@ function expandWikiMentions(markdown, pages, pageAliases, conceptMaps, currentSl
let expanded = line;
for (let index = replacements.length - 1; index >= 0; index -= 1) {
const replacement = replacements[index];
const link = replacement.conceptMap ?
const rendered = replacement.text || (replacement.conceptMap ?
`[${replacement.conceptMap.title}](${cmapRoute(replacement.conceptMap.slug)})` :
`[${replacement.page.title}](${pageRoute(replacement.page.slug)})`;
expanded = expanded.slice(0, replacement.start) + link + expanded.slice(replacement.end);
`[${replacement.page.title}](${pageRoute(replacement.page.slug)})`);
expanded = expanded.slice(0, replacement.start) + rendered + expanded.slice(replacement.end);
}
result.push(expanded);
}