jsdoc icon indicating copy to clipboard operation
jsdoc copied to clipboard

'@' in @example code block tries to render a custom tag

Open dbanksdesign opened this issue 7 years ago • 8 comments

When documenting code with an '@' symbol in the @example block, jsdoc thinks the '@' is a tag and breaks the rendering of the example code

Input code

/**
 * Creates a LESS file with variable definitions based on the style dictionary
 *
 * @example
 * ```
 * @color-background-base: #f0f0f0;
 * @color-background-alt: #eeeeee;
 * ```
 */
function foo() {

}

JSDoc configuration

No configuration, also tried with the markdown plugin enabled, same thing happens.

JSDoc debug output

DEBUG: JSDoc 3.5.5 (Thu, 14 Sep 2017 02:51:54 GMT)
DEBUG: Environment info: {"env":{"conf":{"plugins":[],"recurseDepth":10,"source":{"includePattern":".+\\.js(doc|x)?$","excludePattern":"(^|\\/|\\\\)_"},"sourceType":"module","tags":{"allowUnknownTags":true,"dictionaries":["jsdoc","closure"]},"templates":{"monospaceLinks":false,"cleverLinks":false,"default":{"outputSourceFiles":true}}},"opts":{"_":["test.js"],"debug":true,"destination":"./out/","encoding":"utf8"}}}
DEBUG: Parsing source files: ["/Users/djb/Dev/jsdoctest/test.js"]
Parsing /Users/djb/Dev/jsdoctest/test.js ...
DEBUG: Finished parsing source files.
DEBUG: Indexing doclets...
DEBUG: Adding inherited symbols, mixins, and interface implementations...
DEBUG: Adding borrowed doclets...
DEBUG: Post-processing complete.
Generating output files...
Finished running in 0.23 seconds.

Expected behavior

Either provide a way to escape an '@' sign with a backslash, or have jsdoc ignore any content in triple ticks so that the '@' character does not trigger a tag.

Current behavior

jsdoc reads any '@' symbol as a tag even if it is within a code example.

Your environment

Software Version
JSDoc 3.5.5
Node.js v9.6.0
npm 5.8.0
Operating system OSX 10.12.6

dbanksdesign avatar Apr 17 '18 05:04 dbanksdesign

Pinging this. Is there a workaround for this if this is not a valid use-case?

dbanksdesign avatar May 22 '18 20:05 dbanksdesign

I've rectified this in a crude way; feel free to expand on it if you'd like.

Note that I am running a custom version of JSDoc in my own src/ folder; I'm not pulling from node_modules/ dir.

Inside jsdoc/lib/jsdoc/doclet.js, I've added the following just before the first docletSrc.replace statement:

docletSrc
+   // replace the following @ symbol groups with escaped @ symbols to 
+   // avoid breaking markdown triple-tick code blocks; as JSdoc will 
+   // think it's a doclet tag and try to create a tag object.
+   .replace(/(@:)/g, '@:') // @:
+   .replace(/(@import)/g, '@import') // @import
+   .replace(/(@keyup)/g, '@keyup') // @keyup
+   .replace(/(@click)/g, '@click') // @click
+ 
    .replace(/^(\s*)@(\S)/gm, '$1\\@$2')

This requires me to add additional .replace statements as needed. Not the best or most elegant solution, but it's at least not breaking my Vue SFC @click statements anymore in rendered code blocks.

williampansky avatar Oct 26 '18 17:10 williampansky

any update on this yet? it's relatively difficult to document TypeScript decorators without a way to escape '@' character in example code block.

calscks avatar Aug 09 '21 06:08 calscks

TypeScript also has this issue.

https://github.com/microsoft/TypeScript/issues/47679

I believe that we should find a solution that is compatible with both. TypeScript and JSDoc already have some differences, but I believe we should minimize these as much as possible and coordinate on the best solutions to be as compatible as possible.

trusktr avatar Jan 02 '23 19:01 trusktr

More specifically, I don't think we need to handle @ specifically inside an @example block, but we should be able to escape characters anywhere in a JSDoc comment.

F.e. using \ as an escape character, \@ would render a literal @ in the comment output, and would not consider it the beginning of the tag. We could escape other characters using the same \.

trusktr avatar Jan 02 '23 19:01 trusktr

I was able to escape the @ sign by preceding it with a zero width joiner character. It's a bit of a hack. I'm not sure if it will cause issues down the road either.

char:

image

code:

/**
 * @description handles the setup and teardown of connection for google cloud pubsub
 * @example
 *
 * ```
 * ‌@Connect() // TODO: remove zero width joiner char once jsdocs accommodates
 * connect(): ClientConfig {
 *   const projectId = this.configService.get('SOME_PROJECT_ID')
 *   const credentials = this.configService.get('SOME_CREDENTIALS')
 *   return { projectId, credentials }
 * }
 * ```
 * @returns void
 */

result:

image

woody34 avatar Feb 03 '23 17:02 woody34

More specifically, I don't think we need to handle @ specifically inside an @example block, but we should be able to escape characters anywhere in a JSDoc comment.

+1

This will solve other issues like https://github.com/gajus/eslint-plugin-jsdoc/issues/710 as well.

The zero-width unicode character workarounds in this thread and others are not viable for examples that are meant as boilerplate, as the copied text will include the character and result in runtime errors like: Unexpected "\u2063".

Enteleform avatar Jul 19 '24 00:07 Enteleform

Hey found this now and my usecase is lit html examples with eventlisteners like

 * @example
 * ```js
 * <cap-trigger
 *   visible="false"
 *   local-trigger="true"
 *   \@beginCollide=${(e) => {
 *     console.info(e.target)
 *   }}
 *   \@endCollide=${(e) => {
 *     console.info(e.target)
 *   }}
 *   geometry="primitive:box;width:8;height:8;depth:8;">
 * </cap-trigger>
 *  ```
 *

what i see the \ escaping is not used, is there any other workaround for now?

arpu avatar Sep 12 '24 18:09 arpu