diff --git a/src/loader/babel.ts b/src/loader/babel.ts index 2fd93a4..21ae44b 100644 --- a/src/loader/babel.ts +++ b/src/loader/babel.ts @@ -216,6 +216,10 @@ const babelPluginUntyped: PluginItem = function ( export default babelPluginUntyped; +function isExampleBlock(line = "") { + return line.startsWith("@example"); +} + function containsIncompleteCodeblock(line = "") { const codeDelimiters = line .split("\n") @@ -225,17 +229,51 @@ function containsIncompleteCodeblock(line = "") { function clumpLines(lines: string[], delimiters = [" "], separator = " ") { const clumps: string[] = []; + while (lines.length > 0) { - const line = lines.shift()!; - if ( - (line && !delimiters.includes(line[0]) && clumps.at(-1)) || - containsIncompleteCodeblock(clumps.at(-1)) - ) { + const line = lines.shift() as string; + + // If there is no previous clump, create one + if (!clumps.at(-1)) { + clumps.push(line); + continue; + } + + // If the line starts with a delimiter, create a new clump + if (delimiters.includes(line[0])) { + clumps.push(line); + continue; + } + + // If the previous clump is an example block, append to it + if (isExampleBlock(clumps.at(-1))) { + clumps[clumps.length - 1] += separator + line; + continue; + } + + // If the previous clump is an incomplete code block, append to it + if (containsIncompleteCodeblock(clumps.at(-1))) { clumps[clumps.length - 1] += separator + line; - } else { + continue; + } + + // If the line starts with a code block delimiter, create a new clump + // We need to check this after the previous check to avoid creating a new clump for an incomplete code block + if (line.startsWith("```")) { clumps.push(line); + continue; } + + // Append to the previous clump + if (line) { + clumps[clumps.length - 1] += separator + line; + continue; + } + + // If the line is empty, create a new clump + clumps.push(line); } + return clumps.filter(Boolean); } diff --git a/test/transform.test.ts b/test/transform.test.ts index ad80f89..785e43a 100644 --- a/test/transform.test.ts +++ b/test/transform.test.ts @@ -326,6 +326,62 @@ describe("transform (jsdoc)", () => { }); }); + it("does not split example without codeblock", () => { + const result = transform(` + export default { + /** + * @note This is a note. + * @example + * export default secretNumber = 42 + * + * export default nothing = null + * @type {'src' | 'root'} + */ + srcDir: 'src' + } + `); + expectCodeToMatch(result, /export default ([\S\s]*)$/, { + srcDir: { + $default: "src", + $schema: { + title: "", + tsType: "'src' | 'root'", + description: "", + tags: [ + "@note This is a note.", + "@example\nexport default secretNumber = 42\n\nexport default nothing = null", + ], + }, + }, + }); + }); + + it("supports codeblock without `@example`", () => { + const result = transform(` + export default { + /** + * @note This is a note. + * \`\`\`js + * export default secret + * \`\`\` + * @type {'src' | 'root'} + */ + srcDir: 'src' + } + `); + expectCodeToMatch(result, /export default ([\S\s]*)$/, { + srcDir: { + $default: "src", + $schema: { + title: "", + tsType: "'src' | 'root'", + description: "", + tags: ["@note This is a note.", "```js\nexport default secret\n```"], + }, + }, + }); + }); + it("correctly parses type assertion", () => { const result = transform(` import type { InputObject } from 'untyped'