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 { 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();