1/**
2 * HTML formatting for generated pages.
3 *
4 * Pretty-prints HTML via rehype when enabled.
5 */
6
7import type { Root } from "hast";
8import { unified, type Plugin } from "unified";
9import rehypeFormat from "rehype-format";
10import rehypeParse from "rehype-parse";
11import rehypeStringify from "rehype-stringify";
12import type { Logger } from "../../logging/logger";
13
14export async function formatHtml(
15 rawHtml: string,
16 targetPath: string,
17 options: { prettyPrint: boolean; logger: Logger }
18): Promise<string> {
19 const { prettyPrint, logger } = options;
20 if (!prettyPrint) return rawHtml;
21
22 try {
23 type ParseOptions = Parameters<typeof rehypeParse>[0];
24 type FormatOptions = Parameters<typeof rehypeFormat>[0];
25 type StringifyOptions = Parameters<typeof rehypeStringify>[0];
26
27 const parsePlugin = rehypeParse as Plugin<[ParseOptions?], Root, Root>;
28 const formatPlugin = rehypeFormat as Plugin<[FormatOptions?], Root, Root>;
29 const stringifyPlugin = rehypeStringify as Plugin<[StringifyOptions?], Root, string>;
30
31 const formatted = await unified()
32 .data("settings", { fragment: false })
33 .use(parsePlugin, { fragment: false })
34 .use(formatPlugin, { indent: 2 })
35 .use(stringifyPlugin)
36 .process(rawHtml);
37 return String(formatted);
38 } catch (err) {
39 logger.warn("build.prettyPrintFailed", { path: targetPath, error: String(err) });
40 return rawHtml;
41 }
42}