mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-08 21:45:15 +00:00

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 * 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>
162 lines
5.1 KiB
JavaScript
162 lines
5.1 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 --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);
|