diff --git a/scripts/generate-docs.ts b/scripts/generate-docs.ts
index 5198ae1c..29624589 100644
--- a/scripts/generate-docs.ts
+++ b/scripts/generate-docs.ts
@@ -171,23 +171,57 @@ function markdown(source: string): { html: string; headings: DocHeading[] } {
}
function examplesFrom(readme: string, name: string): string {
- const examples = [...readme.matchAll(/```([^\n]*)\n([\s\S]*?)```/g)]
- .map((match) => ({ language: match[1]!.trim(), code: match[2]!.trim() }))
- .filter((example) => example.code)
- .filter(
- (example, index, all) => all.findIndex((value) => value.code === example.code) === index,
- )
- .slice(0, 4);
- if (!examples.length) {
- examples.push({
- language: "ts",
- code: `import * as packageApi from "@wrnexus/${name}";\n\nconsole.log(packageApi);`,
- });
+ const usage = /^## Usage\s*$([\s\S]*?)(?=^##\s|\s*$)/m.exec(readme)?.[1];
+ if (!usage) throw new Error(`@wrnexus/${name} README must contain a Usage section`);
+
+ const examples: { title: string; language: string; code: string }[] = [];
+ const lines = usage.replace(/\r/g, "").split("\n");
+ let title = "Typical usage";
+ let prose = "";
+ for (let index = 0; index < lines.length; index++) {
+ const line = lines[index]!;
+ const heading = /^#{3,4}\s+(.+)$/.exec(line);
+ if (heading) {
+ title = heading[1]!.replace(/[`*_]/g, "").trim();
+ prose = "";
+ continue;
+ }
+ const fence = /^```(.*)$/.exec(line);
+ if (fence) {
+ const code: string[] = [];
+ index++;
+ while (index < lines.length && !/^```/.test(lines[index]!)) {
+ code.push(lines[index]!);
+ index++;
+ }
+ const value = code.join("\n").trim();
+ const language = fence[1]!.trim();
+ if (value && language !== "text" && !examples.some((example) => example.code === value)) {
+ examples.push({
+ title: title === "Typical usage" && prose ? prose : title,
+ language,
+ code: value,
+ });
+ }
+ prose = "";
+ continue;
+ }
+ if (line.trim() && !/^[-*>|]/.test(line.trim())) {
+ prose = line
+ .replace(/[`*_]/g, "")
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
+ .replace(/:\s*$/, "")
+ .trim();
+ }
+ }
+ if (examples.length < 2) {
+ throw new Error(`@wrnexus/${name} README needs at least two Usage code examples`);
}
return examples
+ .slice(0, 6)
.map(
- (example, index) =>
- `Example ${index + 1}
${escape(example.code)}
`,
+ (example) =>
+ `${inline(example.title)}
${escape(example.code)}
`,
)
.join("");
}