Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Syntax for @example tag #20

Open
octogonz opened this issue May 26, 2018 · 17 comments
Open

RFC: Syntax for @example tag #20

octogonz opened this issue May 26, 2018 · 17 comments
Labels
octogonz-parser-backlog Items for @octogonz to consider during the next iteration on the parser request for comments A proposed addition to the TSDoc spec

Comments

@octogonz
Copy link
Collaborator

octogonz commented May 26, 2018

RFC: Core set of tags for TSDoc brought up the question of the @example tag that could be used to identify examples. I'm forking it into a separate issue since @c69 pointed out that the design is unclear.

Can anyone find samples of its usage in existing documentation systems?

Since TSDoc will support Markdown, how would it interact with that? Maybe something like this?

/**
 * Adds two numbers together.
 * @example
 * Here's a simple example:
 * ```
 * // Prints "2":
 * console.log(add(1,1));
 * ```
 * @example
 * Here's an example with negative numbers:
 * ```
 * // Prints "0":
 * console.log(add(1,-1));
 * ```
 */
export function add(x: number, y: number): number {
}

How would an API reference web site leverage these directives?

@aciccarello

@dend
Copy link

dend commented May 29, 2018

In the case of DocFX, we definitely want to move away from inlined samples and into includes (see: file inclusion). As such, I like the proposal of having the tag be Markdown-ready.

@tenry92
Copy link

tenry92 commented Jun 4, 2018

I always thought @example is always followed by a sample code, or at least a link to an example file.

If there will be some kind of {@include} (see #22), I would suggest using that in conjunction with markdown, as in the first comment:

/**
 * Adds two numbers together.
 * @example
 * Here's a simple example:
 * {@include example1.ts}
 * @example
 * Here's an example with negative numbers:
 * {@include example2.ts}
 */
export function add(x: number, y: number): number {
}

This way, it's easy to include several code snippets within the same example and reuse example codes at several places.

@aciccarello
Copy link

@pgonzal I'm not sure I understand your question but the code you have looks good to me. My main question is where should the example tag block end? Would it be on an empty line or the next block annotation?

@DovydasNavickas
Copy link

@aciccarello I guess your question will be answered here: #12

@octogonz octogonz changed the title Syntax for @example tag RFC: Syntax for @example tag Sep 1, 2018
@octogonz octogonz added the request for comments A proposed addition to the TSDoc spec label Sep 1, 2018
@kiliancs
Copy link

@example could be spec'ed in such a way that it can be used for tests.

/* @example
/* > plusOne(3)
/* 4

One could create a tool that executes plusOne(3) and fails if the result is not 4.

I haven't given much thought to the different scenarios and why this might or might not make sense in the context of JS/TS. Maybe we need a new tag.

/* @example addOne(3)
/* @expect 4

Sorry for the brainstorming.

@aciccarello
Copy link

aciccarello commented Oct 18, 2018

@kiliancs That seems to me like something that should stay in the example code and not be handled by the documentation tool. Interesting idea though.

/**
 * @example
 * Adding one adds one
 * ```typescript
 * import plusOne from 'plus-one';
 * import expect from 'test-lib';
 *
 * const actual = plusOne(3);
 * expect(actual).toEqual(4);
 * ```
 */
export function plusOne(input: number) {
  return input + 1;
}

@vogloblinsky
Copy link

vogloblinsky commented Dec 6, 2018

@pgonzal I can have for Angular documentation tool https://github.com/compodoc/compodoc this kind of @example usage which use TypeScript decorator.

 * @example
 * Usage example
 * ```typescript
 * @Component({selector: 'something'}) export class AppComponent {};
 * ```

@sharwell
Copy link
Member

sharwell commented Dec 6, 2018

Recently I've been starting to question the need for a dedicated @example tag. It seems like ## Example (a Markdown header) may be able to do the job just as well without defining a new tag.

@octogonz
Copy link
Collaborator Author

octogonz commented Dec 6, 2018

I suppose depends on your documentation template. Right now API Extractor renders @example blocks basically as headers like you suggest, with a bit of extra logic to autonumber the examples if there are more than one of them. But you could imagine a more elaborate system that indexes the examples, or shows special icons next to example sections, etc.

@dend Does DocFX treat example sections differently from other sections?

@vogloblinsky
Copy link

Right now API Extractor renders @example blocks

@pgonzal did this work or release in last npm version deployed ?

I just made a test with your playground this morning with my-use case and cannot see informations in the AST generated.

@octogonz
Copy link
Collaborator Author

octogonz commented Dec 6, 2018

The TSDoc Playground does not implement @example because it is currently specified as "extended" standardization level.

API Extractor is a separate project that incorporates TSDoc, but is not itself part of the TSDoc standard. API Extractor supports the @example tag in version 7.0.0 which is still released under a "beta" NPM disttag; i.e. you have to do npm install @microsoft/api-extractor@beta if you want to try that version.

@octogonz
Copy link
Collaborator Author

octogonz commented Dec 6, 2018

BTW if @example is popular, I'm fine with updating the playground to demo this feature. However e.g. @sharwell was questioning that above.

@iansan5653
Copy link

iansan5653 commented Dec 8, 2019

I prefer the markdown tactic as an example might not necessarily be all TypeScript.

On another note, think it would be helpful to support a name/title for examples. Maybe in @example Name - ... format, or take the text on the same line as the tag to be the name. This would help in documentation generation - for example, one could have a documentation page with examples hidden under an accordion, and use the title text as the name of each accordion item.

Example (where text on the same line is the name of the example, and code besides TypeScript is included):

/**
 * Parses a JSON file.
 * @param path - Full path to the file.
 * @returns An object containing the JSON data.
 * @example Parsing a basic JSON file
 * ##Contents of `file.json`:
 * ```json
 * {
 *   exampleItem: "text"
 * }
 * ```
 *
 * ##Usage:
 * ```ts
 * const result = parseFile("file.json");
 * ```
 *
 * ##Result:
 * ```ts
 * {
 *   exampleItem: 'text',
 * }
 * ```
 */

@octogonz
Copy link
Collaborator Author

octogonz commented Dec 9, 2019

That's a good suggestion. Currently API Documenter simply generates names like Example 1, Example 2, etc. Not as informative as it could be.

Maybe in @example Name - ... format, or take the text on the same line as the tag to be the name.

There's already some precedent, where the @throws tag has a convention that the exception name can be specified using text on the same line as the tag.

   /**
    * Retrieves metadata about a book from the catalog.
    *    
    * @param isbnCode - the ISBN number for the book
    * @returns the retrieved book object
    *
    * @throws {@link IsbnSyntaxError}
    * This exception is thrown if the input is not a valid ISBN number.
    *
    * @throws {@link book-lib#BookNotFoundError}
    * Thrown if the ISBN number is valid, but no such book exists in the catalog.
    *
    * @public
    */
    function fetchBookByIsbn(isbnCode: string): Book;

So maybe a similar convention could be used for @example as in your sample. (BTW markdown headers should probably start with #, to avoid making assumptions about the documenter's heading structure.)

So it could be like this:

/**
 * Parses a JSON file.
 *
 * @param path - Full path to the file.
 * @returns An object containing the JSON data.
 *
 * @example Parsing a basic JSON file
 *
 * # Contents of `file.json`
 * ```json
 * {
 *   "exampleItem": "text"
 * }
 * ```
 *
 * # Usage
 * ```ts
 * const result = parseFile("file.json");
 * ```
 *
 * # Result
 * ```ts
 * {
 *   exampleItem: 'text',
 * }
 * ```
 */

...and might get rendered like this:


Example: Parsing a basic JSON file

Contents of file.json

{
  "exampleItem": "text"
}

Usage

const result = parseFile("file.json");

Result

{
  exampleItem: 'text',
}

@octogonz octogonz added the octogonz-parser-backlog Items for @octogonz to consider during the next iteration on the parser label Dec 9, 2019
hosseinmd added a commit to hosseinmd/prettier-plugin-jsdoc that referenced this issue Mar 4, 2021
hosseinmd added a commit to hosseinmd/prettier-plugin-jsdoc that referenced this issue Mar 4, 2021
@braebo
Copy link

braebo commented Oct 8, 2023

The docs mention that inline text should be parsed as headings, but both the api and the playground treat them as normal paragraphs. Is this intentional or just un-implemented?

@braebo
Copy link

braebo commented Jan 16, 2024

Adding example title's also breaks whitespace rendering in VSCode which is a pretty big problem.

I've been able to roll my own type extractor to compensate for the lack of support here (although I would have preferred to be able to just use tsdoc / api-extractor), but alas, I can't roll my own VSCode (nor can TypeStrong/typedoc#2440) 😅

Does VSCode use tsdoc for the tooltips? Or should I open an issue on that repo too? If there's anything I can to do help inspire some movement here, please let me know!

@octogonz
Copy link
Collaborator Author

octogonz commented Jan 17, 2024

Does VSCode use tsdoc for the tooltips? Or should I open an issue on that repo too? If there's anything I can to do help inspire some movement here, please let me know!

No, how I understand it, VS Code implements a proprietary analysis that isn't based on any spec. It's just a best attempt to render the kinds of /** */ comments most commonly encountered in real world code bases.

We could try to improve that. However because TSDoc's goal is to provide a rigorous and unambiguous syntax, a better approach would be to create a VS Code extension specifically for TSDoc. Then we could perfectly parse TSDoc syntax and provide much better rendering.

If someone's interested in contributing to a project like that, let us know. 🙏 In the past this idea was blocked because we were missing the CI infrastructure for publishing extensions to the VS Code marketplace, but Microsoft solved that recently for us as part of setting up the VS Code extension for Rush (another Rush Stack project).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
octogonz-parser-backlog Items for @octogonz to consider during the next iteration on the parser request for comments A proposed addition to the TSDoc spec
Projects
None yet
Development

No branches or pull requests

10 participants