import { resolve, basename } from "path"; import * as fs from "fs"; import { execSync } from "child_process"; const root = resolve(import.meta.dirname, "../.."); const dry = process.argv.includes("--dry"); const bytes2utf8 = new TextDecoder(); /** * Base64 to UTF-8 * @param encoded Base64 encoded string * @returns UTF-8 string */ export const base64Decode = (encoded) => bytes2utf8.decode(Uint8Array.from(atob(encoded), (m) => m.charCodeAt(0))); const yarn = (cmd, stdio = "inherit") => { const script = `yarn run ${cmd}`; if (dry) { return script; } return execSync(script, { stdio }); }; const typlite = (input, output = "-") => { if (output === "-") { // return stdout const res = yarn(`--silent typlite ${input} -`, "pipe"); return res.toString(); } return yarn(`typlite ${input} ${output}`); }; const convert = async (inp, out, opts) => { const input = resolve(root, inp); const output = resolve(root, out); const { before } = opts || {}; const res = typlite(input).trim(); if (dry) { console.log(res); return; } const assetsDir = resolve(output, "../assets/images"); fs.mkdirSync(assetsDir, { recursive: true }); // outline all data "data:image/svg+xml;base64," to render on GitHub correctly const inputName = basename(input); let imageCnt = 0; const outputContent = `\n${before || ""}${res}\n`.replace( /\"data\:image\/svg\+xml\;base64,([^\"]*)\"/g, (_, content) => { const fileName = `${inputName}-inlined${imageCnt}.svg`; imageCnt += 1; fs.writeFileSync(resolve(assetsDir, fileName), base64Decode(content)); return `"./assets/images/${fileName}"`; }, ); await fs.promises.writeFile(output, outputContent); }; const main = async () => { await Promise.all([ convert("docs/tinymist/introduction.typ", "README.md", { before: "# Tinymist\n\n", }), convert("docs/tinymist/release-instruction.typ", "docs/release-instruction.md", { before: "# Release Instructions\n\n", }), convert("docs/tinymist/frontend/emacs.typ", "editors/emacs/README.md", { before: "# Tinymist Emacs Support for Typst\n\n", }), convert("docs/tinymist/frontend/helix.typ", "editors/helix/README.md", { before: "# Tinymist Helix Support for Typst\n\n", }), convert("docs/tinymist/frontend/neovim.typ", "editors/neovim/README.md", { before: "# Tinymist Neovim Support for Typst\n\n", }), convert("docs/tinymist/frontend/sublime-text.typ", "editors/sublime-text/README.md", { before: "# Tinymist Sublime Support for Typst\n\n", }), convert("docs/tinymist/frontend/vscode.typ", "editors/vscode/README.md", { before: "# Tinymist Typst VS Code Extension\n\n", }), convert("docs/tinymist/frontend/zed.typ", "editors/zed/README.md", { before: "# Tinymist Zed Support for Typst\n\n", }), ]); }; main().catch(console.error);