fix: generate package examples from usage guides
This commit is contained in:
+48
-14
@@ -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) =>
|
||||
`<article class="example-card"><h3>Example ${index + 1}</h3><pre data-language="${escape(example.language || "text")}"><code>${escape(example.code)}</code></pre></article>`,
|
||||
(example) =>
|
||||
`<article class="example-card"><h3>${inline(example.title)}</h3><pre data-language="${escape(example.language || "text")}"><code>${escape(example.code)}</code></pre></article>`,
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user