tinymist/scripts/link-docs.mjs
Myriad-Dreamin 223a337736
Some checks are pending
tinymist::ci / Duplicate Actions Detection (push) Waiting to run
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Waiting to run
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Waiting to run
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-2019) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Blocked by required conditions
tinymist::ci / prepare-build (push) Waiting to run
tinymist::ci / build-binary (push) Blocked by required conditions
tinymist::ci / build-vsc-assets (push) Blocked by required conditions
tinymist::ci / build-vscode (push) Blocked by required conditions
tinymist::ci / build-vscode-others (push) Blocked by required conditions
tinymist::ci / publish-vscode (push) Blocked by required conditions
tinymist::gh_pages / build-gh-pages (push) Waiting to run
fix: readme generation (#1754)
* fix: readme generation

* feat: markdown-aware export

* feat: add ieee example

* fix: fix wrong behavior of list parsing and <div> elem parsing

* test: update snapshot

Co-authored-by: Hong Jiarong <me@jrhim.com>

* fix: clippy warnings

* fix: handle br tag as hard break in HTML parsing (#1769)

* fix: handle br tag as hard break in HTML parsing

* Revert "svg gen"

This reverts commit 1ff4c0af33c209a9f653c879f2f7d504bad1ff32.

---------

Co-authored-by: Myriad-Dreamin <camiyoru@gmail.com>

* feat: some md-specific impl

* test: bad changes

---------

Co-authored-by: Hong Jiarong <me@jrhim.com>
2025-05-21 17:45:37 +08:00

162 lines
5.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 --root ${root} ${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);
};
// 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);