mirror of
https://github.com/yusing/godoxy.git
synced 2026-02-22 16:58:02 +01:00
- Convert markdown output to fumadocs MDX - Add api-md2mdx.ts for markdown to MDX transformation - Remove sidebar auto-update functionality - Change output directory from src/impl to content/docs/impl - Update DOCS_DIR path in Makefile to local wiki directory - Copy swagger.json directly instead of generating markdown - Add argparse dependency for CLI argument parsing
115 lines
2.7 KiB
TypeScript
115 lines
2.7 KiB
TypeScript
export function md2mdx(md: string) {
|
|
const indexFirstH2 = md.indexOf("## ");
|
|
if (indexFirstH2 === -1) {
|
|
console.error("## section not found in the file");
|
|
process.exit(1);
|
|
}
|
|
|
|
const h1 = md.slice(0, indexFirstH2);
|
|
const h1Lines = h1.split("\n");
|
|
const keptH1Lines: string[] = [];
|
|
const callouts: string[] = [];
|
|
|
|
for (let i = 0; i < h1Lines.length; i++) {
|
|
const line = h1Lines[i] ?? "";
|
|
const calloutStart = line.match(/^>\s*\[!([a-z0-9_-]+)\]\s*$/i);
|
|
if (calloutStart) {
|
|
const rawCalloutType = (calloutStart[1] ?? "note").toLowerCase();
|
|
const calloutType =
|
|
rawCalloutType === "note"
|
|
? "info"
|
|
: rawCalloutType === "warning"
|
|
? "warn"
|
|
: rawCalloutType;
|
|
const contentLines: string[] = [];
|
|
|
|
i++;
|
|
for (; i < h1Lines.length; i++) {
|
|
const blockLine = h1Lines[i] ?? "";
|
|
if (!blockLine.startsWith(">")) {
|
|
i--;
|
|
break;
|
|
}
|
|
contentLines.push(blockLine.replace(/^>\s?/, ""));
|
|
}
|
|
|
|
while (contentLines[0] === "") {
|
|
contentLines.shift();
|
|
}
|
|
while (contentLines[contentLines.length - 1] === "") {
|
|
contentLines.pop();
|
|
}
|
|
|
|
if (contentLines.length > 0) {
|
|
callouts.push(
|
|
`<Callout type="${calloutType}">\n${contentLines.join("\n")}\n</Callout>`,
|
|
);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
keptH1Lines.push(line);
|
|
}
|
|
|
|
const h1WithoutCallout = keptH1Lines.join("\n");
|
|
const titleMatchResult = h1WithoutCallout.match(
|
|
new RegExp(/^\s*#\s+([^\n]+)/, "im"),
|
|
);
|
|
const title = titleMatchResult?.[1]?.trim() ?? "";
|
|
let description = h1WithoutCallout
|
|
.replace(new RegExp(/^\s*#\s+[^\n]+\n?/, "im"), "")
|
|
.replaceAll(new RegExp(/^\s*>.+$/, "gm"), "")
|
|
.trim();
|
|
// remove trailing full stop
|
|
if (description.endsWith(".")) {
|
|
description = description.slice(0, -1);
|
|
}
|
|
|
|
let header = `---\ntitle: ${title}`;
|
|
if (description) {
|
|
header += `\ndescription: ${description}`;
|
|
}
|
|
header += "\n---";
|
|
|
|
md = md.slice(indexFirstH2);
|
|
const calloutsBlock = callouts.join("\n\n");
|
|
if (calloutsBlock) {
|
|
md = `${header}\n\n${calloutsBlock}\n\n${md}`;
|
|
} else {
|
|
md = `${header}\n\n${md}`;
|
|
}
|
|
|
|
md = md.replaceAll("</br>", "<br/>");
|
|
md = md.replaceAll("<0", "\\<0");
|
|
|
|
return md;
|
|
}
|
|
|
|
async function main() {
|
|
const Parser = await import("argparse").then((m) => m.ArgumentParser);
|
|
|
|
const parser = new Parser({
|
|
description: "Convert API markdown to VitePress MDX",
|
|
});
|
|
parser.add_argument("-i", "--input", {
|
|
help: "Input markdown file",
|
|
required: true,
|
|
});
|
|
parser.add_argument("-o", "--output", {
|
|
help: "Output VitePress MDX file",
|
|
required: true,
|
|
});
|
|
|
|
const args = parser.parse_args();
|
|
const inMdFile = args.input;
|
|
const outMdxFile = args.output;
|
|
|
|
const md = await Bun.file(inMdFile).text();
|
|
const mdx = md2mdx(md);
|
|
await Bun.write(outMdxFile, mdx);
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
await main();
|
|
}
|