Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

comment-parser

yavorskiy14.9mMIT1.4.1TypeScript support: included

Generic JSDoc-like comment parser

jsdoc, comments, parser

readme

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
npm install comment-parser

💡 Check out the Playground

💡 Previous version lives in 0.x branch

Lib mainly provides two pieces Parser and Stringifier.

Parser

Let's go over string parsing:

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

The input source is first parsed into lines, then lines split into tokens, and finally, tokens are processed into blocks of tags

Block

/**
 * Description may go
 * over multiple lines followed by @tags
 * @param {string} name the name parameter
 * @param {any} value the value parameter
 */

Description

/**
 * Description may go
 * over multiple lines followed by @tags

Tags

 * @param {string} name the name parameter
 * @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

[{
  // 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

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

suggest more examples

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.

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

/**
 * 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

suggest more examples

Migrating from 0.x version

Code of pre-1.0 version is forked into 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.

changelog

v1.4.1

  • fix .prettierignore
  • add source trasformation example

v1.4.0

  • ESM compatibility improvements; fixes #159, #161

v1.3.1

  • allow for valid empty jsdoc; fixes #128

v1.3.0

  • add support for custom block markers

v1.2.4

  • reverting engine constraint back to ^12.0.0

v1.2.3

  • publishing missing fix: point package's main to .cjs file

v1.2.2

  • re-export ./util on the top-level for compatibility with older Node
  • point package's main to .cjs file

v1.2.1

  • bump engines per exports issues in earlier Node versions

v1.2.0

  • keep and handle appropriately CR line endings

v1.1.6-beta.3

  • process CRs as a separate .lineEnd toke

v1.1.6-beta.2

  • ESM/CJS compatibility fixes

v1.1.6-beta.1

  • support native ESM

v1.1.6-beta.0

  • keep original CR line endings
  • allow to normalize line endings with crlf transform

v1.1.5

  • drop unused variables
  • add .editorconfig

v1.1.4

  • bugfix fix unsynced lib/

v1.1.3

  • export primitive type on the top level: Markers, Block, Spec, Line, Tokens, Problem

v1.1.2

  • bugfix Allow to build nested tags from name.subname even if name wasn't d
  • bugfix Preserve indentation when extracting comments

v1.1.1

  • add helpers for rewiring Spec.source <-> Spec.tags.source

v1.1.0

  • split tokenizers into separate modules
  • allow multiline {type} definitions - issue #109
  • allow using "=>" in [name=default] defaults – issue #112
  • allow using "=" in quoted [name=default] defaults – issue #112
  • add tokenizers usage example - issue #111

v1.0.0

  • complete rewrite in TS with more flexible API

v0.7.6

  • distinct non-critical errors by providing err.warning

v0.7.5

  • name parsing fixes

v0.7.4

  • node 8 backward compatibility fixes

v0.7.3

  • make stringify result more close to the source

v0.7.2

  • make stringify to start each line with * in multiline comments

v0.7.1

  • ensure non-space characters after asterisk are included in source

v0.7.0

  • allow fenced blocks in tag description, see opts.fence

v0.6.2

  • document TypeScript definitions

v0.6.1

  • adjust strigifier indentation

v0.6.0

  • soft-drop node@6 support
  • migrate to ES6 syntax
  • allow to generate comments out of parsed data

v0.5.5

  • allow loose tag names, e.g. @.tag, @-tag

v0.5.4

  • allow quoted literal names, e.g. @tag "My Var" description

v0.5.3

  • corrected TypeScript definitions

v0.5.2

  • added TypeScript definitions
  • removed readable-stream dependency

v0.5.1

  • Support for tab as separator between tag components.
  • Docs: Indicate when optional is true; default property

v0.5.0

  • line wrapping control with opts.join

v0.4.2

  • tolerate inconsistent lines alignment within block

v0.4.1

  • refactored parsing, allow to not start lines with "* " inside block

v0.3.2

  • fix RegExp for description extraction to allow $ char

v0.3.1

  • use readable-stream fro Node 0.8 comatibility
  • allow to pass optional parameters to parse.file(path [,opts], done)
  • allow parse.stream to work with Buffers in addition to strings

v0.3.0

  • feature allow to use custom parsers
  • feature always include source, no raw_value option needed
  • bugfix always provide optional tag property
  • refactor clean up tests

v0.2.3

  • bugfix Accept /** one line */ comments
  • refactor Get rid of lodash to avoid unnecessary extra size when bundled

v0.2.2

  • feature allow spaces in default values @my-tag {my.type} [name=John Doe]

v0.2.1

  • refactor make line pasing mechanism more tolerable

v0.2.0

  • feature include source line numbers in parsed data
  • feature optionally prevent dotten names expanding

v0.1.2

  • bugfix Allow to build nested tags from name.subname even if name wasn't d
  • bugfix Preserve indentation when extracting comments

v0.1.1

  • improvement parse(source) returns array of all blocks found in source or an empty array
  • bugfix fixed indented blocks parsing

v0.1.0

Initial implementation