58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import type { RemarkPlugin } from "@astrojs/markdown-remark";
|
|
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
import { visit } from "unist-util-visit";
|
|
import { join, resolve, dirname } from "node:path";
|
|
import { spawnSync } from "node:child_process";
|
|
import { tmpdir } from "node:os";
|
|
import { readdir, copyFile } from "node:fs/promises";
|
|
|
|
const remarkTypst: RemarkPlugin = () => {
|
|
const tmp = mkdtempSync(join(tmpdir(), "typst"));
|
|
let ctr = 0;
|
|
|
|
return async (tree, { history }) => {
|
|
const path: string = resolve(history[history.length - 1]!);
|
|
const dir = dirname(path);
|
|
|
|
// Copy all the .typ files in the dir
|
|
for (const file of await readdir(dir)) {
|
|
console.log("checking", file);
|
|
if (file.endsWith(".typ")) {
|
|
const src = resolve(join(dir, file));
|
|
const dst = resolve(join(tmp, file));
|
|
console.log("copying", src, dst);
|
|
await copyFile(src, dst);
|
|
}
|
|
}
|
|
|
|
visit(
|
|
tree,
|
|
(node) => node.type === "code" && node.lang === "typst",
|
|
(node, index, parent) => {
|
|
const doc = resolve(join(tmp, `${ctr}.typ`));
|
|
const docOut = resolve(join(tmp, `${ctr}.svg`));
|
|
ctr += 1;
|
|
|
|
writeFileSync(doc, node.value);
|
|
const result = spawnSync("typst", [
|
|
"compile",
|
|
"--format",
|
|
"svg",
|
|
doc,
|
|
docOut,
|
|
]);
|
|
console.log("OUTPUT", result.stderr.toString());
|
|
|
|
const svgOut = readFileSync(docOut);
|
|
node.type = "html";
|
|
node.value = `
|
|
<div class="svg">
|
|
${svgOut.toString()}
|
|
</div>
|
|
`;
|
|
},
|
|
);
|
|
};
|
|
};
|
|
|
|
export default remarkTypst;
|