import { Playbill, type TaggedComponent } from "@proscenium/playbill"; import sortBy from "lodash-es/sortBy"; import { createMarkdownRenderer, type BoundPlaybill } from "#lib"; import { GlossaryTable } from "./component/glossary"; import { PageHeader } from "./component/header"; import { ItemCard } from "./component/item"; import { MethodSection } from "./component/method"; import { ResourceSection } from "./component/resource"; import { RuleSection } from "./component/rule"; import { SpeciesSection } from "./component/species"; import { renderToString } from "react-dom/server"; import defaultCSS from "./default.css" with { type: "text" }; export async function renderPlaybillToHTML( boundPlaybill: BoundPlaybill, ): Promise { // Make a copy of the playbill to avoid modifying the original // and compile all description markdown const playbill = Playbill.fromSerialized(boundPlaybill.playbill.serialize()); // Prepare a rendering function for markdown that is aware of the playbill binding const renderMarkdown = createMarkdownRenderer(boundPlaybill); // Define a processor function to iterate over all components and process their markdown const processMarkdownInComponent = async (entry: TaggedComponent) => { entry.component.description = await renderMarkdown( entry.component.description, ); if (entry.type === "resource" && entry.component.type === "table") { const newData: string[][] = []; for (const row of entry.component.data) { const newRow: string[] = []; for (const cell of row) { newRow.push(await renderMarkdown(cell)); } newData.push(newRow); } entry.component.data = newData; } }; // Process all components await playbill.processComponents(processMarkdownInComponent); // Soprt rules by their order prop const rulesByOrder = sortBy(Object.values(playbill.rules), "order"); // Prepare stylesheet const cssParts: string[] = []; if (!boundPlaybill.omitDefaultStyles) { cssParts.push(``); } if (boundPlaybill.styles.length > 0) { cssParts.push(``); } const css = cssParts.join("\n"); const body = renderToString( <>
{Object.values(playbill.species).map((species) => ( ))}
{Object.values(playbill.methods).map((method) => ( ))}
{Object.values(playbill.items).map((item) => ( ))}
{rulesByOrder.map((rule) => ( ))}
{}
{Object.values(playbill.resources).map((resource) => ( ))}
, ); // Main document const doc = ` Playbill: ${playbill.name} ${css} ${renderToString()}

${playbill.description}

${body} `; return doc; }