mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-08 13:35:02 +00:00
146 lines
4.7 KiB
JavaScript
146 lines
4.7 KiB
JavaScript
import { resolve, basename, relative } 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) => {
|
||
const assets_flag = dry
|
||
? ""
|
||
: `--assets-path ${relative(root, resolve(output, "../assets/images/", basename(input.slice(0, -4))))}`;
|
||
|
||
// return stdout
|
||
const res = yarn(`--silent typlite ${assets_flag} --root ${root} ${input} -`, "pipe");
|
||
return res.toString();
|
||
};
|
||
|
||
const convert = async (inp, out, opts) => {
|
||
const input = resolve(root, inp);
|
||
const output = resolve(root, out);
|
||
const { before } = opts || {};
|
||
|
||
const res = typlite(input, output).trim();
|
||
if (dry) {
|
||
console.log(res);
|
||
return;
|
||
}
|
||
|
||
const outputContent = `<!-- This file is generated by scripts/link-docs.mjs from ${inp}. Do not edit manually. -->\n${before || ""}${res}\n`;
|
||
await fs.promises.writeFile(output, outputContent);
|
||
};
|
||
|
||
// todo: generate me using typlite.
|
||
const maintainerMd = async () => {
|
||
const maintainers = JSON.parse(yarn(`--silent maintainers --input=action=maintainers`, "pipe"));
|
||
const features = JSON.parse(yarn(`--silent maintainers --input=action=features`, "pipe"));
|
||
|
||
const output = [];
|
||
|
||
output.push("<!-- This file is generated by scripts/link-docs.mjs. Do not edit manually. -->\n");
|
||
output.push("# Tinymist Maintainers\n\n");
|
||
output.push(
|
||
"Tinymist [ˈtaɪni mɪst] is an integrated language service for [Typst](https://typst.app/) [taɪpst].",
|
||
);
|
||
|
||
output.push(
|
||
"\nThis page is generated from [./MAINTAINERS.typ](./MAINTAINERS.typ) and renders information of [maintainers](#maintainers) and [features.](#features)\n",
|
||
);
|
||
|
||
output.push("## Maintainers\n");
|
||
|
||
const italicIt = (it) => `*${it}*`;
|
||
const featureLink = (it) => {
|
||
const feature = features.find((f) => f.name === it);
|
||
if (feature) {
|
||
return `[${it}](#${it.replace(/\s+/g, "-").toLowerCase()})`;
|
||
}
|
||
return it;
|
||
};
|
||
const fsPath = (it) => {
|
||
if (!fs.existsSync(it)) {
|
||
throw new Error(`Path ${it} does not exist!`);
|
||
}
|
||
return `[\`${it}\`](./${it})`;
|
||
};
|
||
|
||
for (const maintainer of maintainers) {
|
||
output.push(`- [**${maintainer["name"]}**](https://github.com/${maintainer["github-name"]})`);
|
||
output.push(` - Email: ${maintainer.email}`);
|
||
if (maintainer.maintains.length > 0) {
|
||
const rendered = maintainer.maintains.map(featureLink).map(italicIt);
|
||
if (rendered.length > 1) {
|
||
const last = rendered.pop();
|
||
output.push(` - Maintains: ${rendered.join(", ")}, and ${last}`);
|
||
} else {
|
||
output.push(` - Maintains: ${rendered.join(", ")}`);
|
||
}
|
||
}
|
||
output.push("");
|
||
}
|
||
|
||
output.push("## Features\n");
|
||
for (const feature of features) {
|
||
output.push(`### ${feature.name}`);
|
||
output.push(`${feature.description}`);
|
||
output.push(`- Scope: ${feature.scope.map(fsPath).join(", ")}`);
|
||
}
|
||
|
||
const outPath = resolve(root, "MAINTAINERS.md");
|
||
const outputContent = output.join("\n");
|
||
if (dry) {
|
||
console.log(content);
|
||
return;
|
||
}
|
||
|
||
await fs.promises.writeFile(outPath, 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",
|
||
}),
|
||
maintainerMd(),
|
||
]);
|
||
};
|
||
|
||
main().catch(console.error);
|