Improved markdown rendering, allow hiding components
This commit is contained in:
parent
d200d48903
commit
a9a979c5f8
10 changed files with 598 additions and 100 deletions
|
@ -1,6 +1,6 @@
|
|||
import { Playbill, type TaggedComponent } from "@proscenium/playbill";
|
||||
import sortBy from "lodash-es/sortBy";
|
||||
import { renderMarkdown } from "#lib";
|
||||
import { createMarkdownRenderer, type BoundPlaybill } from "#lib";
|
||||
import { GlossaryTable } from "./component/glossary";
|
||||
import { PageHeader } from "./component/header";
|
||||
import { ItemCard } from "./component/item";
|
||||
|
@ -10,61 +10,64 @@ import { RuleSection } from "./component/rule";
|
|||
import { SpeciesSection } from "./component/species";
|
||||
import { renderToString } from "react-dom/server";
|
||||
|
||||
interface HTMLRenderOptions {
|
||||
styles?: string;
|
||||
}
|
||||
|
||||
async function processMarkdownInComponent(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;
|
||||
}
|
||||
}
|
||||
|
||||
export async function renderPlaybillToHTML(
|
||||
playbillToRender: Playbill,
|
||||
opts: HTMLRenderOptions = {},
|
||||
boundPlaybill: BoundPlaybill,
|
||||
): Promise<string> {
|
||||
// Make a copy of the playbill to avoid modifying the original
|
||||
// and compile all description markdown
|
||||
const playbill = Playbill.fromSerialized(playbillToRender.serialize());
|
||||
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 css = opts.styles ? `<style>${opts.styles}</style>` : "";
|
||||
const css = `<style>${boundPlaybill.styles}</style>`;
|
||||
|
||||
const body = renderToString(<>
|
||||
<article id="species" className="view">
|
||||
{Object.values(playbill.species).map((species) => <SpeciesSection key={species.id} species={species} playbill={playbill} />)}
|
||||
</article>
|
||||
|
||||
<article id="methods" className="view">
|
||||
<article id="methods" className="view" style={{ display: "none" }}>
|
||||
{Object.values(playbill.methods).map((method) => <MethodSection key={method.id} method={method} playbill={playbill} />)}
|
||||
</article>
|
||||
|
||||
<article id="items" className="view">
|
||||
<article id="items" className="view" style={{ display: "none" }}>
|
||||
{Object.values(playbill.items).map((item) => <ItemCard key={item.id} item={item} />)}
|
||||
</article>
|
||||
|
||||
<article id="rules" className="view">
|
||||
<article id="rules" className="view" style={{ display: "none" }}>
|
||||
{rulesByOrder.map((rule) => <RuleSection key={rule.id} rule={rule} />)}
|
||||
</article>
|
||||
|
||||
<article id="glossary" className="view">
|
||||
<article id="glossary" className="view" style={{ display: "none" }}>
|
||||
{<GlossaryTable glossary={playbill.glossary} />}
|
||||
</article>
|
||||
|
||||
<article id="resources" className="view">
|
||||
<article id="resources" className="view" style={{ display: "none" }}>
|
||||
{Object.values(playbill.resources).map((resource) => <ResourceSection key={resource.id} resource={resource} />)}
|
||||
</article>
|
||||
</>);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue