blog/plugin/remark-typst.ts
Michael Zhang 7a1b2b9787
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
trying to get typst rendering working for svgs
2024-09-26 18:09:45 -05:00

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;