From 53b7713d5751082ac281b06255f4f7bcf98a710c Mon Sep 17 00:00:00 2001 From: barbapapazes Date: Sun, 25 Feb 2024 18:20:13 +0100 Subject: [PATCH 1/4] fix: respect multines example block --- src/loader/babel.ts | 11 +++++------ test/transform.test.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/loader/babel.ts b/src/loader/babel.ts index c1b0d28..2f1f662 100644 --- a/src/loader/babel.ts +++ b/src/loader/babel.ts @@ -210,20 +210,19 @@ const babelPluginUntyped: PluginItem = function ( export default babelPluginUntyped; -function containsIncompleteCodeblock(line = "") { - const codeDelimiters = line - .split("\n") - .filter((line) => line.startsWith("```")).length; - return !!(codeDelimiters % 2); +function isExampleBlock(line = "") { + return line.includes("@example"); } 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)) + // Support for example blocks in mutliline comments (last line is an example and next line is not a tag) + (isExampleBlock(clumps.at(-1)) && !line.startsWith("@")) ) { clumps[clumps.length - 1] += separator + line; } else { diff --git a/test/transform.test.ts b/test/transform.test.ts index 7d4232a..d08a734 100644 --- a/test/transform.test.ts +++ b/test/transform.test.ts @@ -326,6 +326,36 @@ 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("correctly parses type assertion", () => { const result = transform(` import type { InputObject } from 'untyped' From d2442b43f4e2586c16f9197a59af64df696500f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Est=C3=A9ban?= Date: Sun, 25 Feb 2024 18:25:03 +0100 Subject: [PATCH 2/4] Update src/loader/babel.ts --- src/loader/babel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loader/babel.ts b/src/loader/babel.ts index 2f1f662..e6e512a 100644 --- a/src/loader/babel.ts +++ b/src/loader/babel.ts @@ -221,7 +221,7 @@ function clumpLines(lines: string[], delimiters = [" "], separator = " ") { if ( (line && !delimiters.includes(line[0]) && clumps.at(-1)) || - // Support for example blocks in mutliline comments (last line is an example and next line is not a tag) + // Support for example block with blank line (last line is an example and next line is not a tag) (isExampleBlock(clumps.at(-1)) && !line.startsWith("@")) ) { clumps[clumps.length - 1] += separator + line; From 441b85aa4798cb0d105601ae4ac0dd8fe77d8786 Mon Sep 17 00:00:00 2001 From: barbapapazes Date: Thu, 3 Oct 2024 12:17:57 +0200 Subject: [PATCH 3/4] refactor --- src/loader/babel.ts | 52 ++++++++++++++++++++++++++++++++++++------ test/transform.test.ts | 26 +++++++++++++++++++++ 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/loader/babel.ts b/src/loader/babel.ts index 58689ed..d362e05 100644 --- a/src/loader/babel.ts +++ b/src/loader/babel.ts @@ -217,24 +217,62 @@ const babelPluginUntyped: PluginItem = function ( export default babelPluginUntyped; function isExampleBlock(line = "") { - return line.includes("@example"); + return line.startsWith("@example"); +} + +function containsIncompleteCodeblock(line = "") { + const codeDelimiters = line + .split("\n") + .filter((line) => line.startsWith("```")).length; + return !!(codeDelimiters % 2); } function clumpLines(lines: string[], delimiters = [" "], separator = " ") { const clumps: string[] = []; + while (lines.length > 0) { - const line = lines.shift(); + const line = lines.shift() as string; - if ( - (line && !delimiters.includes(line[0]) && clumps.at(-1)) || - // Support for example block with blank line (last line is an example and next line is not a tag) - (isExampleBlock(clumps.at(-1)) && !line.startsWith("@")) - ) { + // 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; + 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; + } + + // If the line is empty, create a new clump + if (line) { + clumps[clumps.length - 1] += separator + line; + continue; } else { clumps.push(line); } } + return clumps.filter(Boolean); } diff --git a/test/transform.test.ts b/test/transform.test.ts index ce72924..785e43a 100644 --- a/test/transform.test.ts +++ b/test/transform.test.ts @@ -356,6 +356,32 @@ describe("transform (jsdoc)", () => { }); }); + 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' From be5d453c089aa173b5370f1ed0d2500eb0dc920b Mon Sep 17 00:00:00 2001 From: barbapapazes Date: Thu, 3 Oct 2024 12:19:24 +0200 Subject: [PATCH 4/4] refactor --- src/loader/babel.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/loader/babel.ts b/src/loader/babel.ts index d362e05..21ae44b 100644 --- a/src/loader/babel.ts +++ b/src/loader/babel.ts @@ -264,13 +264,14 @@ function clumpLines(lines: string[], delimiters = [" "], separator = " ") { continue; } - // If the line is empty, create a new clump + // Append to the previous clump if (line) { clumps[clumps.length - 1] += separator + line; continue; - } else { - clumps.push(line); } + + // If the line is empty, create a new clump + clumps.push(line); } return clumps.filter(Boolean);