HTML renderer for Wikidot markup.
bun add @wdprlib/renderimport { parse, processWikitext } from "@wdprlib/parser";
import { renderToHtml, renderWikitext } from "@wdprlib/render";
import type { PageContext } from "@wdprlib/render";
const { ast } = parse("**Hello** world");
// Basic rendering
const html = renderToHtml(ast);
// With page context and resolvers
const pageContext: PageContext = {
pageName: "main",
site: "mysite",
domain: "mysite.example.com",
pageExists: (name) => checkPageExists(name),
// Image attachments of the page, shown by the content-less [[gallery]]
// form (image/* with resized variants; createdAt enables order="created_at")
files: [{ name: "photo.jpg", createdAt: 1700000000 }],
};
const html = renderToHtml(ast, {
page: pageContext,
footnotes: ast.footnotes,
resolvers: {
user: (username) => ({ name: username, displayName: "Display Name" }),
htmlBlockUrl: (index) => `/local--html/page/${index}`,
},
});For an asynchronous application pipeline, parse first and render second. @wdprlib/render
does not import or depend on @wdprlib/parser:
const document = await processWikitext(source, {
page: {
fullName: "docs:start",
unixName: "start",
tags: ["docs"],
urlPath: "/docs:start",
},
dataProvider,
});
const result = await renderWikitext(document, {
styleMode: "separate",
resolvers: {
resolvePageExistence: async (pages) => findExistingPages(pages),
resolveHtmlBlockUrl: async ({ index, content, page }) => {
const hash = await storeHtmlBlock(content);
return `/local--html/${page.fullName}/${index}/${hash}`;
},
},
});
result.html; // contains no <style> tags in separate mode
result.styles;
result.htmlBlocks;
result.diagnostics;
result.dependencies;[[embed]]accepts HTTPS iframes only. Inlinestyleattributes are removed; use the allowedwidthandheightattributes for sizing.- Local image and gallery paths reject traversal segments, encoded path components, backslashes, NUL bytes, query strings, and fragments.
createSettings("page")andDEFAULT_SETTINGSkeep[[module CSS]]disabled. Enable it only when the CSS source is trusted:
import { createSettings } from "@wdprlib/ast";
const trustedPageSettings = {
...createSettings("page"),
allowStyleElements: true,
};- HTML block iframes use an empty
sandboxattribute by default. SethtmlBlockSandbox: nullonly when Wikidot-compatible unsandboxed execution is explicitly required. Avoid combiningallow-scriptsandallow-same-originfor same-origin content because that can negate the sandbox.
- HTML generation from AST
- Footnote and bibliography rendering
- User link resolution
- Embed block with configurable allowlist
- Math rendering (via Temml)
- XSS protection (via DOMPurify)
- @wdprlib/ast - AST type definitions
- @wdprlib/parser - Wikidot markup parser
- @wdprlib/decompiler - HTML to Wikidot decompiler
- @wdprlib/runtime - Client-side runtime
AGPL-3.0 - See LICENSE