81 lines
2.9 KiB
TypeScript
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();
|