Merge pull request 'fix: decode HTML entities in wikilinks before re-escaping' (#11) from dev into main

This commit was merged in pull request #11.
This commit is contained in:
2026-03-26 02:50:00 +00:00
+13 -2
View File
@@ -5,6 +5,17 @@ function escapeHtmlAttr(s: string): string {
return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
// Decode HTML entities that marked introduces before we re-escape for our own output.
// Order matters: &amp; must be last to avoid double-decoding.
function decodeHtmlEntities(s: string): string {
return s
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&amp;/g, "&");
}
export function extractTags(body: string): string[] {
const cleaned = body.replace(CODE_FENCE_RE, "");
const tags = new Set<string>();
@@ -39,8 +50,8 @@ export function linkifyWikilinks(html: string): string {
.map((part, i) => {
if (i % 2 === 1) return part;
return part.replace(WIKILINK_RE, (_full, title: string, display?: string) => {
const trimmed = title.trim();
const label = display || trimmed;
const trimmed = decodeHtmlEntities(title.trim());
const label = display ? decodeHtmlEntities(display) : trimmed;
const encoded = encodeURIComponent(trimmed);
return `<a class="wikilink" data-title="${escapeHtmlAttr(trimmed)}" href="/notes/by-title?title=${encoded}">${escapeHtmlAttr(label)}</a>`;
});