tinymist/scripts/link-docs.mjs
Myriad-Dreamin 4cbe35a286
feat: employ l10n to tinymist-cli and vscode extension (#1505)
* feat: runtime translation

* feat: poc of rust translation

* feat: clean up implementation

* feat: initialize correctly

* dev: remove dirty log

* dev: rename l10nMsg

* fix: desc

* feat: update assets building

* feat: update assets building

* build: update cargo.lock

* fix: warnings

* fix: warnings

* dev: expose api

* fix: compile error

* fix: compile errors in scripts
2025-03-15 10:38:07 +08:00

95 lines
3 KiB
JavaScript

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 =
`<!-- This file is generated by scripts/link-docs.mjs from ${inp}. Do not edit manually. -->\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);