Convert rendering to jsx

This commit is contained in:
Endeavorance 2025-03-19 15:57:56 -04:00
parent 0f72d048ee
commit d1b632e83c
25 changed files with 422 additions and 513 deletions

View file

@ -15,17 +15,21 @@ import { loadYAMLFileOrFail } from "#util";
import { ComponentFile } from "./component-file";
import { FileNotFoundError } from "./errors";
// binding.yaml file schema
const BindingSchema = z.object({
extend: z.string().optional(),
id: z.string().default("playbill"),
name: z.string().default("Unnamed playbill"),
author: z.string().optional(),
description: z.string().optional(),
author: z.string().default("Someone"),
description: z.string().default("No description provided"),
version: z.string().default("0.0.0"),
files: z.array(z.string()).default(["**/*.yaml", "**/*.md"]),
styles: z.array(z.string()).optional(),
styles: z
.union([z.string(), z.array(z.string())])
.transform((val) => (Array.isArray(val) ? val : [val]))
.default([]),
terms: z.record(z.string(), z.string()).default({}),
});
type Binding = z.infer<typeof BindingSchema>;
@ -37,15 +41,15 @@ export interface BoundPlaybill {
bindingFilePath: string;
bindingFileDirname: string;
includedFiles: string[];
componentFiles: ComponentFile[];
// Binding properties
id: string;
name: string;
author: string;
version: string;
description: string;
styles?: string;
styles: string;
playbill: Playbill;
}
@ -98,20 +102,19 @@ export async function loadFromBinding(
}
// Load any specified stylesheets
let styles = "";
if (binding.styles && binding.styles.length > 0) {
for (const style of binding.styles) {
const cssFilePath = path.resolve(bindingFileDirname, style);
const cssFile = Bun.file(cssFilePath);
const cssFileExists = await cssFile.exists();
const loadedStyles: string[] = [];
for (const style of binding.styles) {
const cssFilePath = path.resolve(bindingFileDirname, style);
const cssFile = Bun.file(cssFilePath);
const cssFileExists = await cssFile.exists();
if (cssFileExists) {
styles += `${await cssFile.text()}\n`;
} else {
throw new FileNotFoundError(cssFilePath);
}
if (cssFileExists) {
loadedStyles.push(await cssFile.text());
} else {
throw new FileNotFoundError(cssFilePath);
}
}
const styles = loadedStyles.join("\n");
// Scan for all files matching the globs
const allFilePaths: string[] = [];
@ -154,7 +157,6 @@ export async function loadFromBinding(
const abilities: Ability[] = [];
const bluprints: Blueprint[] = [];
const glossaries: Record<string, string[]>[] = [];
const methods: Method[] = [];
const species: Species[] = [];
const items: Item[] = [];
@ -173,9 +175,6 @@ export async function loadFromBinding(
case "blueprint":
bluprints.push(component.component);
break;
case "glossary":
glossaries.push(component.component);
break;
case "method":
methods.push(component.component);
break;
@ -232,12 +231,8 @@ export async function loadFromBinding(
}
// Add all definitions
for (const glossary of glossaries) {
for (const [term, definitions] of Object.entries(glossary)) {
for (const definition of definitions) {
playbill.addDefinition(term, definition);
}
}
for (const [term, definition] of Object.entries(binding.terms)) {
playbill.addDefinition(term, definition);
}
return {
@ -245,14 +240,14 @@ export async function loadFromBinding(
bindingFilePath: bindingPath,
bindingFileDirname,
includedFiles: filePathsWithoutBindingFile,
componentFiles,
id: binding.id,
name: binding.name,
author: binding.author ?? "Anonymous",
description: binding.description ?? "",
version: binding.version,
styles: styles.length > 0 ? styles : undefined,
styles,
playbill,
};

View file

@ -1,14 +0,0 @@
export function html(
strings: TemplateStringsArray,
...values: unknown[]
): string {
const [first, ...rest] = strings;
let str = first;
for (let i = 0; i < rest.length; i++) {
str += values[i];
str += rest[i];
}
return str.trim();
}

View file

@ -2,4 +2,3 @@ export * from "./errors";
export * from "./markdown";
export * from "./component-file";
export * from "./binding";
export * from "./html";

View file

@ -21,7 +21,6 @@ marked.use(plugin);
* @returns A promise resolving to the HTML representation of the markdown
*/
export async function renderMarkdown(markdown: string): Promise<string> {
// TODO: Custom render tags for links, emphasis, and strong
return await marked.parse(markdown, {
async: true,
gfm: true,
@ -60,23 +59,3 @@ export function extractMarkdown(content: string): string {
}
return content.replace(FRONTMATTER_REGEX, "").trim();
}
/**
* Combine yaml frontmatter and markdown into a single string
* @param markdown The markdown to combine with frontmatter
* @param frontmatter The frontmatter shape to combine with markdown
* @returns A combined document with yaml frontmatter and markdown below
*/
export function combineMarkdownAndFrontmatter(
markdown: string,
frontmatter: unknown,
) {
const frontmatterToWrite: unknown = structuredClone(frontmatter);
return `---
${YAML.stringify(frontmatterToWrite)}
---
${markdown.trim()}
`;
}