feat(markdown): basic support hash-based wikilinks

This commit is contained in:
Elian Doran
2026-04-17 07:49:38 +03:00
parent e33446c219
commit 9f4c3ed35a
3 changed files with 31 additions and 3 deletions

View File

@@ -79,4 +79,10 @@ describe("renderWithSourceLines", () => {
const html = renderWithSourceLines("Energy: $e=mc^2$.");
expect(html).toContain('<span class="math-tex">');
});
it("renders [[wikilinks]] with hash-router hrefs so the preview navigates correctly", () => {
const html = renderWithSourceLines("See [[abc123]] for details.");
expect(html).toContain('class="reference-link"');
expect(html).toContain('href="#root/abc123"');
});
});

View File

@@ -149,7 +149,10 @@ export function renderWithSourceLines(src: string): string {
if (!NON_RENDERED_TOKENS.has(token.type)) lines.push(startLine);
}
const html = renderToHtml(src, "", { sanitize: (h) => DOMPurify.sanitize(h) });
const html = renderToHtml(src, "", {
sanitize: (h) => DOMPurify.sanitize(h),
wikiLink: { formatHref: (id) => `#root/${id}` }
});
if (!html) return "";
const container = document.createElement("div");

View File

@@ -1,7 +1,14 @@
import { Marked, Renderer, type Tokens } from "marked";
import { getMimeTypeFromMarkdownName, MIME_TYPE_AUTO, normalizeMimeTypeForCKEditor } from "./mime_type.js";
import { transclusionExtension, wikiLinkExtension } from "./marked_extensions.js";
import {
createTransclusionExtension,
createWikiLinkExtension,
transclusionExtension,
type TransclusionOptions,
wikiLinkExtension,
type WikiLinkOptions
} from "./marked_extensions.js";
/**
* Mapping from markdown admonition keywords (case-insensitive) to the ids
@@ -24,6 +31,15 @@ export interface RenderToHtmlOptions {
* - client: `DOMPurify.sanitize`
*/
sanitize: (dirtyHtml: string) => string;
/**
* How `[[noteId]]` wiki-links should be rendered. Defaults to the
* server-side format (`href="/noteId"`), which is what imports want.
* Browser callers that navigate via the hash router should pass
* `{ formatHref: (id) => `#root/${id}` }`.
*/
wikiLink?: WikiLinkOptions;
/** Same as {@link wikiLink}, for `![[noteId]]` transclusions. */
transclusion?: TransclusionOptions;
}
function escapeHtml(str: string): string {
@@ -253,7 +269,10 @@ export function renderToHtml(content: string, title: string, options: RenderToHt
const marked = new Marked({ async: false });
marked.use({
// Order is important, especially for wikilinks.
extensions: [ transclusionExtension, wikiLinkExtension ]
extensions: [
options.transclusion ? createTransclusionExtension(options.transclusion) : transclusionExtension,
options.wikiLink ? createWikiLinkExtension(options.wikiLink) : wikiLinkExtension
]
});
const renderer = new CustomMarkdownRenderer({ async: false });