221 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # comment-parser
 | ||
| 
 | ||
| `comment-parser` is a library helping to handle Generic JSDoc-style comments. It is
 | ||
| 
 | ||
| - **language-agnostic** – no semantics enforced. You decide what tags are and what they mean. And it can be used with any language supporting `/** */` source comments.
 | ||
| - **no dependencies** – it is compact and environment-agnostic, can be run on both the server and browser sides
 | ||
| - **highly customizable** – with a little code you can deeply customize how comments are parsed
 | ||
| - **bidirectional** - you can write comment blocks back to the source after updating or formatting
 | ||
| - **strictly typed** - comes with generated `d.ts` data definitions since written in TypeScript
 | ||
| 
 | ||
| ```sh
 | ||
| npm install comment-parser
 | ||
| ```
 | ||
| 
 | ||
| > 💡 Check out the [Playground](https://syavorsky.github.io/comment-parser)
 | ||
| 
 | ||
| > 💡 Previous version lives in [0.x](https://github.com/syavorsky/comment-parser/tree/0.x) branch
 | ||
| 
 | ||
| Lib mainly provides two pieces [Parser](#Parser) and [Stringifier](#Stringifier).
 | ||
| 
 | ||
| ## Parser
 | ||
| 
 | ||
| Let's go over string parsing:
 | ||
| 
 | ||
| ```js
 | ||
| const { parse } = require('comment-parser/lib')
 | ||
| 
 | ||
| const source = `
 | ||
| /**
 | ||
|  * Description may go
 | ||
|  * over few lines followed by @tags
 | ||
|  * @param {string} name the name parameter
 | ||
|  * @param {any} value the value of any type
 | ||
|  */`
 | ||
| 
 | ||
| const parsed = parse(source)
 | ||
| ```
 | ||
| 
 | ||
| Lib source code is written in TypeScript and all data shapes are conveniently available for your IDE of choice. All types described below can be found in [primitives.ts](src/primitives.ts)
 | ||
| 
 | ||
| The input source is first parsed into lines, then lines split into tokens, and finally, tokens are processed into blocks of tags
 | ||
| 
 | ||
| ### Block
 | ||
| 
 | ||
| ```js
 | ||
| /**
 | ||
|  * Description may go
 | ||
|  * over multiple lines followed by @tags
 | ||
|  * @param {string} name the name parameter
 | ||
|  * @param {any} value the value parameter
 | ||
|  */
 | ||
| ```
 | ||
| 
 | ||
| ### Description
 | ||
| 
 | ||
| ```js
 | ||
| /**
 | ||
|  * Description may go
 | ||
|  * over multiple lines followed by @tags
 | ||
| ```
 | ||
| 
 | ||
| ### Tags
 | ||
| 
 | ||
| ```js
 | ||
|  * @param {string} name the name parameter
 | ||
| ```
 | ||
| 
 | ||
| ```js
 | ||
|  * @param {any} value the value parameter
 | ||
|  */
 | ||
| ```
 | ||
| 
 | ||
| ### Tokens
 | ||
| 
 | ||
| ```
 | ||
| |line|start|delimiter|postDelimiter|tag   |postTag|name |postName|type    |postType|description                     |end|
 | ||
| |----|-----|---------|-------------|------|-------|-----|--------|--------|--------|--------------------------------|---|
 | ||
| |   0|{2}  |/**      |             |      |       |     |        |        |        |                                |   |
 | ||
| |   1|{3}  |*        |{1}          |      |       |     |        |        |        |Description may go              |   |
 | ||
| |   2|{3}  |*        |{1}          |      |       |     |        |        |        |over few lines followed by @tags|   |
 | ||
| |   3|{3}  |*        |{1}          |@param|{1}    |name |{1}     |{string}|{1}     |the name parameter              |   |
 | ||
| |   4|{3}  |*        |{1}          |@param|{1}    |value|{1}     |{any}   |{1}     |the value of any type           |   |
 | ||
| |   5|{3}  |         |             |      |       |     |        |        |        |                                |*/ |
 | ||
| ```
 | ||
| 
 | ||
| ### Result
 | ||
| 
 | ||
| The result is an array of Block objects, see the full output on the [playground](https://syavorsky.github.io/comment-parser)
 | ||
| 
 | ||
| ```js
 | ||
| [{
 | ||
|   // uppper text of the comment, overall block description
 | ||
|   description: 'Description may go over multiple lines followed by @tags',
 | ||
|   // list of block tags: @param, @param
 | ||
|   tags: [{
 | ||
|     // tokens.tag without "@"
 | ||
|     tag: 'param',
 | ||
|     // unwrapped tokens.name
 | ||
|     name: 'name',
 | ||
|     // unwrapped tokens.type
 | ||
|     type: 'string',
 | ||
|     // true, if tokens.name is [optional]
 | ||
|     optional: false,
 | ||
|     // default value if optional [name=default] has one
 | ||
|     default: undefined,
 | ||
|     // tokens.description assembled from a siongle or multiple lines
 | ||
|     description: 'the name parameter',
 | ||
|     // problems occured while parsing this tag section, subset of ../problems array
 | ||
|     problems: [],
 | ||
|     // source lines processed for extracting this tag, "slice" of the ../source item reference
 | ||
|     source: [ ... ],
 | ||
|   }, ... ],
 | ||
|   // source is an array of `Line` items having the source
 | ||
|   // line number and `Tokens` that can be assembled back into
 | ||
|   // the line string preserving original formatting
 | ||
|   source: [{
 | ||
|     // source line number
 | ||
|     number: 1,
 | ||
|     // source line string
 | ||
|     source: "/**",
 | ||
|     // source line tokens
 | ||
|     tokens: {
 | ||
|       // indentation
 | ||
|       start: "",
 | ||
|       // delimiter, either '/**', '*/', '*', or ''. Mid lines may have no delimiters
 | ||
|       delimiter: "/**",
 | ||
|       // space between delimiter and tag
 | ||
|       postDelimiter: "",
 | ||
|       // tag starting with "@"
 | ||
|       tag: "",
 | ||
|       // space between tag and type
 | ||
|       postTag: "",
 | ||
|       // name with no whitespaces or "multiple words" wrapped into quotes. May occure in [name] and [name=default] forms
 | ||
|       name: "",
 | ||
|       // space between name and type
 | ||
|       postName: "",
 | ||
|       // type is has to be {wrapped} into curlies otherwise will be omitted
 | ||
|       type: "",
 | ||
|       // space between type and description
 | ||
|       postType: "",
 | ||
|       // description is basicaly rest of the line
 | ||
|       description: "",
 | ||
|       // closing */ marker if present
 | ||
|       end: ""
 | ||
|     }
 | ||
|   }, ... ],
 | ||
|   // problems occured while parsing the block
 | ||
|   problems: [],
 | ||
| }];
 | ||
| ```
 | ||
| 
 | ||
| While `.source[].tokens` are not providing readable annotation information, they are essential for tracing data origins and assembling string blocks with `stringify`
 | ||
| 
 | ||
| ### options
 | ||
| 
 | ||
| ```ts
 | ||
| interface Options {
 | ||
|   // start count for source line numbers
 | ||
|   startLine: number;
 | ||
|   // escaping chars sequence marking wrapped content literal for the parser
 | ||
|   fence: string;
 | ||
|   // block and comment description compaction strategy
 | ||
|   spacing: 'compact' | 'preserve';
 | ||
|   // tokenizer functions extracting name, type, and description out of tag, see Tokenizer
 | ||
|   tokenizers: Tokenizer[];
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| examples
 | ||
| - [default config](https://syavorsky.github.io/comment-parser/#parse-defaults)
 | ||
| - [line numbers control](https://syavorsky.github.io/comment-parser/#parse-line-numbering)
 | ||
| - [description spacing](https://syavorsky.github.io/comment-parser/#parse-spacing)
 | ||
| - [escaping](https://syavorsky.github.io/comment-parser/#parse-escaping)
 | ||
| - [explore the origin source](https://syavorsky.github.io/comment-parser/#parse-source-exploration)
 | ||
| 
 | ||
| [suggest more examples](https://github.com/syavorsky/comment-parser/issues/new?title=example+suggestion%3A+...&labels=example,parser)
 | ||
| 
 | ||
| ## Stringifier
 | ||
| 
 | ||
| The stringifier is an important piece used by other tools updating the source code. It goes over `Block.source[].tokens` items and assembles them back to the string. It might be used with various transforms applied before stringifying.
 | ||
| 
 | ||
| ```js
 | ||
| const { parse, stringify, transforms: {flow, align, indent} } = require('comment-parser');
 | ||
| 
 | ||
| const source = `
 | ||
|   /**
 | ||
|    * Description may go
 | ||
|    * over multiple lines followed by @tags
 | ||
|    *
 | ||
| * @my-tag {my.type} my-name description line 1
 | ||
|       description line 2
 | ||
|     * description line 3
 | ||
|    */`;
 | ||
| 
 | ||
| const parsed = parse(source);
 | ||
| const transform = flow(align(), indent(0))
 | ||
| console.log(stringify(transform(parsed[0])));
 | ||
| ```
 | ||
| 
 | ||
| ### Result
 | ||
| 
 | ||
| ```js
 | ||
| /**
 | ||
|  * Description may go
 | ||
|  * over multiple lines followed by @tags
 | ||
|  *
 | ||
|  * @my-tag {my.type} my-name description line 1
 | ||
|                              description line 2
 | ||
|  *                           description line 3
 | ||
|  */
 | ||
| ```
 | ||
| 
 | ||
| examples
 | ||
| - [format comments](https://syavorsky.github.io/comment-parser/#stringify-formatting)
 | ||
| 
 | ||
| [suggest more examples](https://github.com/syavorsky/comment-parser/issues/new?title=example+suggestion%3A+...&labels=example,stringifier)
 | ||
| 
 | ||
| ## Migrating from 0.x version
 | ||
| 
 | ||
| Code of pre-1.0 version is forked into [0.x](https://github.com/syavorsky/comment-parser/tree/0.x) and will phase out eventually. Please file the issue if you find some previously existing functionality can't be achieved with 1.x API. Check out [migration notes](migrate-1.0.md).
 |