mathu/scripts/compile-content.ts
2024-04-24 18:54:55 -07:00

81 lines
2.9 KiB
TypeScript

import fs from "fs";
import { getDirname } from '../util/dirname';
import path from "path";
import { Mathuscript, parseMathuscript } from "../src/client/player/parse";
import { writeFileSync, mkdirSync, rmSync } from 'fs';
import {execa} from 'execa';
import hash from "object-hash";
const __dirname = getDirname(import.meta);
// Function to convert LaTeX to SVG
async function latexToSvg(latex: string, dir: string, tempDir: string | null): Promise<string> {
try {
// const dir = path.join(__dirname, "..", "src", "server", "public", "svgs");
tempDir = tempDir ?? path.join(dir, "temp");
mkdirSync(tempDir, {recursive: true});
const fname = hash(latex);
const tempFileName = path.join(tempDir, fname);
const outFileName = path.join(dir, fname);
writeFileSync(`${tempFileName}.tex`, latex);
// Run LaTeX to generate a DVI file
console.log("generating dvi file");
await execa('latex', ['-halt-on-error', `-output-directory=${tempDir}`, `${tempFileName}.tex`]);
// Convert DVI to SVG
console.log("converting to svg");
await execa('dvisvgm', [`${tempFileName}.dvi`, '-n', '-o', `${outFileName}.svg`]);
console.log("cleaning up temp files");
rmSync(tempDir, {force: true, recursive: true});
return `${fname}.svg`;
} catch (error) {
console.error('Error converting LaTeX to SVG:', error);
throw Error('Error converting LaTeX to SVG');
}
}
const contentDir = path.join(__dirname, "..", "src", "content");
const publicDir = path.join(__dirname, "..", "src", "server", "public");
const assetsDir = path.join(publicDir, "assets");
const compiledAssetsDir = path.join(assetsDir, "compiled");
const compileToDir = path.join(__dirname, "..", "src", "client", "content");
const preamblePath = path.join(contentDir, "preamble.tex");
const sectionsDir = path.join(contentDir, "sections");
const compileContents = async () => {
fs.rmSync(compileToDir, {force: true, recursive: true});
fs.mkdirSync(compileToDir, {recursive: true});
const sectionFiles = fs.readdirSync(sectionsDir);
const sections: {name: string; text: string, parsed: Mathuscript}[] = [];
sectionFiles.forEach(sectionFile => {
const fullName = path.join(sectionsDir, sectionFile);
console.log("Reading", sectionFile);
const fileText = fs.readFileSync(fullName, "utf8");
sections.push({
name: sectionFile,
text: fileText,
parsed: parseMathuscript(fileText),
});
})
const preamble = fs.readFileSync(preamblePath, "utf8");
for (const section of sections) {
console.log("Processing", section.name);
for (const step of section.parsed.filter(step => step.name === "board")) {
console.log('Step');
if (step.text.trim()) {
const svgPath = await latexToSvg(`${preamble}\n\n\\begin{document}\n${step.text}\n\\end{document}\n`, compiledAssetsDir, null);
step.text = svgPath;
}
}
}
fs.writeFileSync(path.join(compileToDir, "content.ts"), `export const content = {sections: ${JSON.stringify(sections)}}`);
}
await compileContents();