diff --git a/src/descriptionFormatter.ts b/src/descriptionFormatter.ts index 25838f0..4765a49 100644 --- a/src/descriptionFormatter.ts +++ b/src/descriptionFormatter.ts @@ -217,122 +217,132 @@ function formatDescription( return ((mdAst as Root).children as Content[]) .map((ast, index) => { - if (ast.type === "listItem") { - let _listCount = `\n${intention}- `; - // .replace(/((?!(^))\n)/g, "\n" + _intention); - if (typeof (mdAst as List).start === "number") { - const count = index + (((mdAst as List).start as number) ?? 1); - _listCount = `\n${intention}${count}. `; - } + switch (ast.type) { + case "listItem": { + let _listCount = `\n${intention}- `; + // .replace(/((?!(^))\n)/g, "\n" + _intention); + if (typeof (mdAst as List).start === "number") { + const count = index + (((mdAst as List).start as number) ?? 1); + _listCount = `\n${intention}${count}. `; + } - const _intention = intention + " ".repeat(_listCount.length - 1); + const _intention = intention + " ".repeat(_listCount.length - 1); - const result = stringyfy(ast, _intention, mdAst).trim(); + const result = stringyfy(ast, _intention, mdAst).trim(); - return `${_listCount}${result}`; - } + return `${_listCount}${result}`; + } - if (ast.type === "list") { - let end = ""; - /** - * Add empty line after list if that is end of description - * issue: {@link https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/98} - */ - if ( - tag !== DESCRIPTION && - mdAst.type === "root" && - index === mdAst.children.length - 1 - ) { - end = "\n"; + case "list": { + let end = ""; + /** + * Add empty line after list if that is end of description + * issue: {@link https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/98} + */ + if ( + tag !== DESCRIPTION && + mdAst.type === "root" && + index === mdAst.children.length - 1 + ) { + end = "\n"; + } + return `\n${stringyfy(ast, intention, mdAst)}${end}`; } - return `\n${stringyfy(ast, intention, mdAst)}${end}`; - } - if (ast.type === "paragraph") { - const paragraph = stringyfy(ast, intention, parent); - if ((ast as any).costumeType === TABLE) { - return paragraph; + case "paragraph": { + const paragraph = stringyfy(ast, intention, parent); + if ((ast as any).costumeType === TABLE) { + return paragraph; + } + + return `\n\n${paragraph + /** + * Break by backslash\ + * issue: https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/102 + */ + .split("\\\n") + .map((_paragraph) => { + const links: string[] = []; + // Find jsdoc links and remove spaces + _paragraph = _paragraph.replace( + /{@(link|linkcode|linkplain)[\s](([^{}])*)}/g, + (_, tag: string, link: string) => { + links.push(link); + + return `{@${tag}${"_".repeat(link.length)}}`; + }, + ); + + _paragraph = _paragraph.replace(/\s+/g, " "); // Make single line + + if ( + options.jsdocCapitalizeDescription && + !TAGS_PEV_FORMATE_DESCRIPTION.includes(tag) + ) + _paragraph = capitalizer(_paragraph); + if (options.jsdocDescriptionWithDot) + _paragraph = _paragraph.replace(/([\w\p{L}])$/u, "$1."); // Insert dot if needed + + let result = breakDescriptionToLines( + _paragraph, + printWidth, + intention, + ); + + // Replace links + result = result.replace( + /{@(link|linkcode|linkplain)([_]+)}/g, + (original: string, tag: string, underline: string) => { + const link = links[0]; + + if (link.length === underline.length) { + links.shift(); + return `{@${tag} ${link}}`; + } + + return original; + }, + ); + + return result; + }) + .join("\\\n")}`; } - return `\n\n${paragraph - /** - * Break by backslash\ - * issue: https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/102 - */ - .split("\\\n") - .map((_paragraph) => { - const links: string[] = []; - // Find jsdoc links and remove spaces - _paragraph = _paragraph.replace( - /{@(link|linkcode|linkplain)[\s](([^{}])*)}/g, - (_, tag: string, link: string) => { - links.push(link); - - return `{@${tag}${"_".repeat(link.length)}}`; - }, - ); - - _paragraph = _paragraph.replace(/\s+/g, " "); // Make single line - - if ( - options.jsdocCapitalizeDescription && - !TAGS_PEV_FORMATE_DESCRIPTION.includes(tag) - ) - _paragraph = capitalizer(_paragraph); - if (options.jsdocDescriptionWithDot) - _paragraph = _paragraph.replace(/([\w\p{L}])$/u, "$1."); // Insert dot if needed - - let result = breakDescriptionToLines( - _paragraph, - printWidth, - intention, - ); - - // Replace links - result = result.replace( - /{@(link|linkcode|linkplain)([_]+)}/g, - (original: string, tag: string, underline: string) => { - const link = links[0]; - - if (link.length === underline.length) { - links.shift(); - return `{@${tag} ${link}}`; - } - - return original; - }, - ); - - return result; - }) - .join("\\\n")}`; - } + case "strong": { + return `**${stringyfy(ast, intention, mdAst)}**`; + } - if (ast.type === "strong") { - return `**${stringyfy(ast, intention, mdAst)}**`; - } + case "emphasis": { + return `_${stringyfy(ast, intention, mdAst)}_`; + } - if (ast.type === "emphasis") { - return `_${stringyfy(ast, intention, mdAst)}_`; - } + case "heading": { + return `\n\n${intention}${"#".repeat(ast.depth)} ${stringyfy( + ast, + intention, + mdAst, + )}`; + } - if (ast.type === "heading") { - return `\n\n${intention}${"#".repeat(ast.depth)} ${stringyfy( - ast, - intention, - mdAst, - )}`; - } + case "link": + case "image": { + return `[${stringyfy(ast, intention, mdAst)}](${ast.url})`; + } - if (ast.type === "link" || ast.type === "image") { - return `[${stringyfy(ast, intention, mdAst)}](${ast.url})`; - } + case "linkReference": { + return `[${stringyfy(ast, intention, mdAst)}][${ast.label}]`; + } + case "definition": { + return `\n\n[${ast.label}]: [${ast.url}]`; + } - if (ast.type === "blockquote") { - const paragraph = stringyfy(ast, "", mdAst); - return `${intention}> ${paragraph - .trim() - .replace(/(\n+)/g, `$1${intention}> `)}`; + case "blockquote": { + const paragraph = stringyfy(ast, "", mdAst); + return `${intention}> ${paragraph + .trim() + .replace(/(\n+)/g, `$1${intention}> `)}`; + } } return stringyfy(ast, intention, mdAst); }) diff --git a/tests/__snapshots__/descriptions.test.ts.snap b/tests/__snapshots__/descriptions.test.ts.snap index 7332adc..e377580 100644 --- a/tests/__snapshots__/descriptions.test.ts.snap +++ b/tests/__snapshots__/descriptions.test.ts.snap @@ -434,6 +434,17 @@ exports[`Not Capitalizing 2`] = ` " `; +exports[`Reference-style Links 1`] = ` +"/** + * Name of something. + * + * See [documentation][1] for more details. + * + * [1]: [https://www.documentation.com] + */ +" +`; + exports[`code in description 1`] = ` "/** * \`Touchable\`: Taps done right. @@ -755,7 +766,9 @@ exports[`matches prettier markdown format 1`] = ` * * - List * - With a [link] (/to/somewhere) - * - And another oneExample title + * - And [another one][another one] + * + * [another one]: [http://example.com] * * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur * consectetur maximus risus, sed maximus tellus tincidunt et. diff --git a/tests/descriptions.test.ts b/tests/descriptions.test.ts index 237056e..07487bc 100644 --- a/tests/descriptions.test.ts +++ b/tests/descriptions.test.ts @@ -1003,3 +1003,17 @@ test("Link ", () => { expect(result).toMatchSnapshot(); }); + +test("Reference-style Links ", () => { + const result = subject(` + /** + * Name of something. + * + * See [documentation][1] for more details. + * + * [1]: https://www.documentation.com + */ +`); + + expect(result).toMatchSnapshot(); +});