const fs = require('fs');
const path = require('path');
const scriptDir = __dirname;
const katexJsPath = path.join(scriptDir, 'assets', 'katex.min.js');
const katexCssPath = path.join(scriptDir, 'assets', 'katex.min.css');
const code = fs.readFileSync(katexJsPath, 'utf8');
const katexCss = fs.readFileSync(katexCssPath, 'utf8');
const m = { exports: {} };
const fn = new Function('module', 'exports', code);
fn(m, m.exports);
const katex = m.exports;
let eqCounter = 0;
function renderMath(text) {
eqCounter = 0;
// First replace block math $$ ... $$
let output = text.replace(/\$\$([\s\S]+?)\$\$/g, (match, eq) => {
eqCounter++;
const rawEq = eq.trim();
try {
const mathHtml = katex.renderToString(rawEq, {
displayMode: true,
output: 'htmlAndMathml',
throwOnError: false,
strict: false
});
return `
| ${mathHtml} | (${eqCounter}) |
`;
} catch (e) {
console.error('KaTeX block error on:', rawEq, e);
return match;
}
});
// Next replace inline math $ ... $ (excluding escaped \$)
output = output.replace(/(? {
const rawEq = eq.trim();
try {
return katex.renderToString(rawEq, {
displayMode: false,
output: 'htmlAndMathml',
throwOnError: false,
strict: false
});
} catch (e) {
console.error('KaTeX inline error on:', rawEq, e);
return match;
}
});
// Also replace KaTeX CSS placeholder if present
if (output.includes('/* __KATEX_CSS__ */')) {
output = output.replace('/* __KATEX_CSS__ */', katexCss);
}
return output;
}
module.exports = { renderMath, katexCss };
if (require.main === module) {
const inputFile = process.argv[2];
const outputFile = process.argv[3] || inputFile;
if (inputFile) {
const raw = fs.readFileSync(inputFile, 'utf8');
const rendered = renderMath(raw);
fs.writeFileSync(outputFile, rendered, 'utf8');
console.log(`Pre-rendered KaTeX math from ${inputFile} -> ${outputFile}`);
}
}