Git Product home page Git Product logo

dmd's Issues

Address npm-audit warning about handlebars

                       === npm audit security report ===                        
                                                                                
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ handlebars                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ jsdoc-to-markdown [dev]                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ jsdoc-to-markdown > dmd > handlebars                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/755                       │
└───────────────┴──────────────────────────────────────────────────────────────┘

From https://nodesecurity.io/advisories/755:

Remediation

Upgrade to version 4.0.13 or later.

is this output expected?

Input:

/**
 * @name Debaser
 * @public       
 * @param {string} [name] Unique name of this Debaser instance.
 * @constructor
 */
var Debaser = function Debaser(name) {
    // stuff
};

/**
 * @description Install all stubs in queue.
 * @memberof Debaser
 * @param {Object} [opts] Optional settings object
 * @param {boolean} [opts.persist=false] Do not flush the queue upon installation
 */
Debaser.prototype.debase = function debase(opts) {
    // stuff
};

Output:

<a name="new_Debaser"></a>
##new Debaser([name])
**Params**

- \[name\] `string` - Unique name of this Debaser instance.  

<a name="Debaser#debase"></a>
##debaser.debase([opts])
Install all stubs in queue.

**Params**

- \[opts\] `Object` - Optional settings object  
  - \[persist=false\] `boolean` - Do not flush the queue upon installation  

Notice the lowercase debaser.debase([opts]). Would have expected something like Debaser.prototype.debase([opts]). @instance tag has no effect nor does using @class instead. Not sure if this is a dmd or jsdoc thing.

Of note is there is something else called debaser; is case-sensitivity an issue?

How to output class field members separately from function members?

I am trying out jsdoc-to-markdown and I have an hbs template that contains this:

{{#class name="MyClassName"~}}
{{>member-index~}}
{{>separator~}}
{{>members~}}
{{/class}}

It works pretty well, except that all field and function members are listed in one big list. I was looking for something like a field-index and a method-index.

I don't see any documentation on what kind of partials are available to use. I actually changed {{#module ...}} to {{#class}} on a guess. Here's a better picture of what I think I'm looking for:

{{#class name="MyClassName"~}}
{{>field-index~}}
{{>method-index~}}
{{>separator~}}
{{>fields~}}
{{>methods~}}
{{/class}}

Is there anything like that?

Add @summary to default templates

Not 100% sure, but I think that the @summary jsdoc tag is not added in the default markdown templates. If this is the case I could make a make a pull request later today (for the next branch) with support for it.

Cannot resolve paths of custom plugins, if they are not in node_modules directory structure

Symptom

When using dmd module as a component, as a part of other projects (e.g.: gulp-jsdoc-to-markdown), when specifying own plugins, the moduleSearch() function in dmd.js cannot properly resolve the path of given moduleName.

Use Case

Using gulp-jsdoc-to-markdown:

// using gulp

const gulp = require("gulp"),
      doc  = require("gulp-jsdoc-to-markdown"),

gulp.task("doc::generate", function() {
    return gulp.src("/vagrant/src/*.js")
        .pipe(doc({
            plugin : ["/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js"]
        }))
        .pipe(gulp.dest("/vagrant/doc"));
});

gulp-jsdoc-to-markdown passes the options Object _untouched_ regarding the .plugin property to dmd via jsdoc-to-markdown.

Check the call chain:

  1. gulp-jsdoc-to-markdown.js
  2. jsdoc-to-markdown.js
  3. dmd.js

During the gulp.task run, dmd tries to resolve the given plugin paths via the moduleSearch() function.

This function tries to resolve the given plugin path by splitting the given plugin path into chunks separated by DS, and then joins them with "node_modules" embedding between the chunks iteratively.

If dmd is used outside of its directory structure (e.g.: as a component), this method will fail, when the specified plugin is not in "node_modules".

console.log() output in Vagrant VM, when moduleSearch() tries to resolve the given plugin path

// NOTE: the given plugin path is "/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js"
// as can be seen in the previous gulp example

modulePath: /vagrant/tasks/gulp/node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
modulePath: /vagrant/tasks/node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
modulePath: /vagrant/node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
modulePath: /node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js

You can see, that the moduleSearch() function tries to resolve the plugin's path, but upon resolving the path, it embeds "node_modules" into the path, that it checks iteratively.

The plugin is not in a node_modules folder or folder structure, as it is a custom one, a modified one for own purposes and also it is not recommended to put other code into node's node_modules folder by other means, than node modifying its contents (e.g.: npm install) as the content of node_modules can often change, also it is generally ignored by git.

Reproduction

Use Vagrant via this gist:

  1. start the vm via vagrant up
  2. after the provision, install gulp-jsdoc-to-markdown and dmd-plugin-example via npm
    (if you encounter any npm-related issue, check the gist mentioned above as it may contain the solution)
  3. create a small .js file with valid jsdoc tags,
    like those can be found here
  4. create a gulp task similar to that above mentioned before and use your previously created .js file with valid jsdoc tags
  5. copy dmd-plugin-example from node_modules into your project,
    for example YourProjectPath/doc/dmd-plugin-example/
  6. run the gulp task with the specified full path to
    your dmd-plugin-example (e.g.: YourProjectPath/doc/dmd-plugin-example/lib/dmd-plugin-example.js)
    as can be seen in the previously mentioned gulp example above
  7. you will get an error, like:
    Error: Cannot find plugin: YourProjectPath/doc/dmd-plugin-example/lib/dmd-plugin-example.js
    although the plugin exists under the path specified before running the gulp task

Resolution

This pull request fixes this issue through a minor patch.

This fix resolves this unintended behaviour, by relying the full, normalized, unfiltered path testing and using only, when the general plugin path testing method mentioned above failed, so old code, libraries and other dependents will work without any modifications.

Need better support for Windows line endings

Output docs are messed up because most of the jsdoc2md code (in all repos) only handles Unix line endings (\n).

For example, this line is splitting only on LF line endings. This particular line is giving me problems (examples with captions are missing the example code) because even though that line doesn't account for CRLF, splitting on LF should still give somewhat reasonable output, but in my case it doesn't because somewhere before that line all LFs were removed and now the string being split only contains CRs.

You could alter that one split to use /\r|\r\n|\n/ which would fix that specific problem, but it doesn't fix the real root of the problem, which is the lack of support for Windows line endings.

Maximum call stack size exceeded

I had a whole bunch of source files that caused jsdoc2md to throw RangeError: Maximum call stack size exceeded. when I attempted to render them. I managed to reduce the issue down to this minimal reproduction (with v 5.0.3):

Foo.js:

/** */
export class Foo {
  constructor() { }
}

template.hbs:

{{#class name="Foo"}}{{>docs}}{{/class}}

Result:

$ jsdoc2md --files ./Foo.js --template ./template.hbs
RangeError: Maximum call stack size exceeded

It doesn't appear to matter whether or not there is content in the jsdoc block, it seems like the only things required to trigger it are a doc block before the class and the class must have a constructor.

More info, if it's helpful...
$ jsdoc2md --version
5.0.3

$ jsdoc2md --files ./Foo.js --template ./template.hbs --config
{
  "files": [
    "./Foo.js"
  ],
  "template": "./template.hbs"
}

$ jsdoc2md --files ./Foo.js --template ./template.hbs --json
[
  {
    "id": "Foo",
    "longname": "Foo",
    "name": "Foo",
    "kind": "class",
    "scope": "instance",
    "memberof": "Foo",
    "meta": {
      "lineno": 1,
      "filename": "Foo.js",
      "path": "/Users/jasonk/jsdoc2md-repro"
    },
    "order": 0
  }
]

$ jsdoc2md --files ./Foo.js --template ./template.hbs --jsdoc
[
  {
    "comment": "/** */",
    "meta": {
      "range": [
        7,
        44
      ],
      "filename": "Foo.js",
      "lineno": 1,
      "columnno": 7,
      "path": "/Users/jasonk/jsdoc2md-repro",
      "code": {
        "id": "astnode100000002",
        "name": "exports.Foo",
        "type": "ClassDeclaration"
      }
    },
    "name": "Foo",
    "longname": "Foo",
    "kind": "class",
    "scope": "global",
    "undocumented": true
  },
  {
    "comment": "",
    "meta": {
      "range": [
        14,
        44
      ],
      "filename": "Foo.js",
      "lineno": 1,
      "columnno": 14,
      "path": "/Users/jasonk/jsdoc2md-repro",
      "code": {
        "id": "astnode100000003",
        "name": "Foo",
        "type": "ClassDeclaration",
        "paramnames": []
      }
    },
    "undocumented": true,
    "name": "Foo",
    "longname": "Foo",
    "kind": "class",
    "scope": "global"
  },
  {
    "comment": "",
    "meta": {
      "range": [
        26,
        42
      ],
      "filename": "Foo.js",
      "lineno": 1,
      "columnno": 26,
      "path": "/Users/jasonk/jsdoc2md-repro",
      "code": {
        "id": "astnode100000006",
        "name": "exports.Foo",
        "type": "MethodDefinition",
        "paramnames": []
      },
      "vars": {
        "": null
      }
    },
    "undocumented": true,
    "name": "Foo",
    "longname": "Foo#Foo",
    "kind": "class",
    "memberof": "Foo",
    "scope": "instance",
    "params": []
  },
  {
    "comment": "",
    "meta": {
      "range": [
        26,
        42
      ],
      "filename": "Foo.js",
      "lineno": 1,
      "columnno": 26,
      "path": "/Users/jasonk/jsdoc2md-repro",
      "code": {
        "id": "astnode100000006",
        "name": "exports.Foo",
        "type": "MethodDefinition",
        "paramnames": []
      }
    },
    "name": "Foo",
    "longname": "Foo",
    "kind": "class",
    "memberof": "Foo",
    "scope": "instance"
  },
  {
    "kind": "package",
    "longname": "package:undefined",
    "files": [
      "/Users/jasonk/jsdoc2md-repro/Foo.js"
    ]
  }
]

@typicalname separation for any parent

When using typicalName in a class, the typical name gets applied to the instance, and the name gets applied which is beautiful. However, I wonder why this type of is limited to parents of class kind? There are many other scenarios where this would be applied nicely exactly the same way.

Simplified example of how I want jsdoc2md to work

/**
 * @exports myFunction
 * @typicalname otherFunction
 */
var myFunction = function() {
    /**
     * Documented as otherFunction.instanceMember
     * @member instanceMember
     * @memberof myFunction
     */
    this.instanceMember = 1;
};

/**
 * Should be documented as myFunction.defaultValue
 * @name defaultValue
 * @memberof myFunction
 */
myFunction.defaultValue = 2;

// then using the function somewhere else without having it as a class nor using `new`
var otherFunction = function() {};
myFunction.apply(otherFunction)

So, there would be scenarios for most parents to have the instance typical name separation. My suggestion is to remove the limit to the class parents. Otherwise another tag @instanceName could be added that works for all parents. It could also be extended with @staticName & @innerName.

For now, I just forked and removed the class parent check, which works perfectly for all my cases. I could make a PR if you like.

@hideconstructor does not hide constructor

Hi,

I'm using @hideconstructor to hide constructor from markdown documents. I even coupled it with @private, but constructor is always documented.

Example (I tried every combination of @private and @hideconstructor)

/**
 * Some details
 * @public
 * @hideconstructor
 */
class MyClass {
  /**
   * Constructor details
   * @private
   * @hideconstructor
   */
  constructor() {
    this.attr = 1;
  }
}

Kind Regards,

whitespace at the end of a line

I started playing with jsdoc-to-markdown to automate generating some API docs for https://github.com/approvals/Approvals.NodeJS.

I noticed that the api docs generated some output with extra whitespace at the end of some lines.

My challenge with this is if I open my editor (where I have "trimTrailingWhitespace": true) any readme mods I make will trim this trailing whitespace.

Then my "test" that verifies that the readme docs are the same as what's generated from the tool are equivalent will always make me copy back the whitespace.

I cloned this repo and started to take a look - but it's hard to tell what files have whitespace at the end on purpose vs what is not necessary.

Any thoughts?

For now, I'm going to write some code to trim trailing whitepsace before writing the docs out as a bandaid - but wanted to see if this would be worth adjusting at the source?

{@link <namepath>} will break if "{@link" is at line ending

This example

// Link is generated

    /**
     * Calculates a suggestion for the region which can be used as input for
     * {@link cascadeOverlapAllWindows}. The suggested region is printed to the console and returned
     * by this method.
     */

works as expected, while the following will not generate a link, but put literally {@link cascadeOverlapAllWindows} in the output.

// No link generated

    /**
     * Calculates a suggestion for the region which can be used as input for {@link
     * cascadeOverlapAllWindows}. The suggested region is printed to the console and returned by
     * this method.
     */

In JSDoc both will generate a correct result.

failing when cache-point is 0.4.1

I've been trying to debug this error for several hours

node_modules/jsdoc2md-stats/lib/jsdoc2md-stats.js:96
        throw err
        ^
Error: The partial docs could not be found

after I compared my packages with another working project, I saw a difference on one of the dependencies version (cache-point).
It looks like it works fine with 0.4.0, but not 0.4.1
I had to add this to my package.json:

"resolutions": {
  "cache-point": "0.4.0"
}

so I think it's better to change package.json to use [email protected] for now (instead of cache-point@^0.4.0)

NPM audit warning for [email protected]

Minor issue, since this package isn't intended to run on a server, etc.

However, it's nice to see 0 vulnerabilities.

┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ marked                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=0.7.0                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ jsdoc-to-markdown [dev]                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ jsdoc-to-markdown > dmd > marked                             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1076                            │
└───────────────┴──────────────────────────────────────────────────────────────┘
found 1 low severity vulnerability in 10848 scanned packages

Accept json generated by docchi

I love the way dmd generates Markdown documentation, but jsdoc2md uses JSDoc to parse the code and comments, and JSDoc has very poor ES6 support.

I ran across docchi recently, and I wonder whether it is compatible with dmd, and what would be required to make them work together.

Enhancement: Keep parameter list on one line

I have a couple minor enhancements to the params list

  • Add a colon after **Params** followed by a blank line so the list that starts after it is rendered by a wider collection of applications.
  • Keep the name, type, and description that follows on the same line. Simply add a ~ to the closing if that comes after linked-type-list so it becomes {{~/if}}.
  • Skip rendering the **Params** all together if there are none in the list (not implemented here)

Before:

{{#params}}**Params**
{{#each this~}}
{{indent}}- {{name}}{{#if type}} {{>linked-type-list types=type.names delimiter=" | " }}{{/if}}{{#unless (equal defaultvalue undefined)}} {{>defaultvalue equals=true ~}}{{/unless}}{{#if description}} - {{{inlineLinks description}}}{{/if}}
{{/each}}

{{/params~}}

After:

{{#params}}**Params**:

{{#each this~}}
{{indent}}- {{name}} {{#if type~}}{{>linked-type-list types=type.names delimiter=" | " }} {{~/if}}{{#unless (equal defaultvalue undefined)}} {{>defaultvalue equals=true ~}}{{/unless}}{{#if description}} - {{{inlineLinks description}}}{{/if}}
{{/each}}

{{/params~}}

How stable is the partial hierarchy for overriding purposes?

I've been making thankful use of the ability to override partials. I override partials that are included by others, and I override partials that include others.

By explicitly allowing this, you have essentially made the entire partial hierarchy part of the public API of dmd. I'd just like to make sure: can I be confident that my overrides will continue to function when I update dmd?

It must be tempting for you to refactor this stuff now and then. But strictly speaking, whenever you do this, it is a breaking change and according to semantic versioning you'd need to increment the major version number.

What is your policy w.r.t. this issue? Thanks!

@example does not render in monospace

In order to have your @example tag render in monospace, you need to do this:

/** 
 * @description does the damn thing
 * @param {Thing} damnThing Damn thing to do
 * @example
 * ```
 * doThe(damnThing);
 * ```
 */
var doThe = function doThe(damnThing) {
  // does it
});

I would expect @example to render in monospace regardless of the presence of ``` or extra indent.

I have a fix for this which I can probably submit later. Wanted to know if you agreed.

@file or @overview tags ignored

Summary

jsdoc tags @file and its synonims @overview and @fileoverview seem to be ignored by jsdoc-to-markdown

Steps to reproduce

Create a file with the following contents:

'use strict';

/**
 * @file A sample file
 */

/**
 * @function foo
 */
function foo () {
  return 'bar';
}

Run jsdoc2md:

$ jsdoc2md file.js
<a name="foo"></a>

## foo()
**Kind**: global function

As you can see the contents for the @file tag are not included in the generated markdown.

Other information

Using version 1.3.6. of jsdoc-to-markdown

@param Support Anchors in Collection of @typedef Types

Given a typedef:

/**
 * Playback position expressed in bars:quarters:sixteenths format (e.g. `"1:2:0"`)
 * @typedef {string} transportTime
 * @global
 */

When that type is used in a param:

@param {transportTime} [opt.time=0:0:0] - The [transportTime]{@link transportTime} at which playback will begin

dmd will create an anchor for the type:

| [opt.time] | <code>[transportTime](#transportTime)</code> | <code>0:0:0</code> | The [transportTime](#transportTime) at which playback will begin |

That nifty feature is not supported for collections:

@param {Array.<Array<transportTime, note, noteDuration>>} [opt.noteData=[]] - See the typedefs for [transportTime]{@link transportTime}, [note]{@link note}, and [noteDuration]{@link noteDuration}
| [opt.noteData] | <code>Array.&lt;Array.&lt;transportTime, note, noteDuration&gt;&gt;</code> | <code>[]</code> | See the typedefs for [transportTime](#transportTime), [note](#note), and [noteDuration](#noteDuration) |

Example

NPM Header Formatting Issue

This could be considered a bug in NPM's markdown parser rather than dmd, but it still may be worth adjusting for. The following markdown snippet generated by dmd:

## Modules
<dl>
<dt><a href="#module_pixiPianoRoll">pixiPianoRoll</a></dt>
<dd><p>JavaScript 2D WebGL / Canvas animated piano roll</p>
</dd>
</dl>
## Typedefs
<dl>
<dt><a href="#transportTime">transportTime</a> : <code>string</code></dt>
<dd><p>Playback position expressed in bars:quarters:sixteenths format (e.g. <code>&quot;1:2:0&quot;</code>)</p>
</dd>
<dt><a href="#note">note</a> : <code>string</code> | <code>number</code></dt>
<dd><p>Musical note expressed in <a href="https://en.wikipedia.org/wiki/Scientific_pitch_notation">Scientific notation</a>, <a href="https://en.wikipedia.org/wiki/Helmholtz_pitch_notation">Helmholtz notation</a>, <a href="https://en.wikipedia.org/wiki/Piano_key_frequencies">piano key number</a>, <a href="https://en.wikipedia.org/wiki/Audio_frequency">audio frequency</a> (the closest note will be used), or <a href="https://en.wikipedia.org/wiki/MIDI">MIDI</a> note number</p>
</dd>
<dt><a href="#noteDuration">noteDuration</a> : <code>string</code> | <code>number</code></dt>
<dd><p>Note duration expressed as a number (e.g. <code>1</code> for a whole note) or string (e.g. <code>&quot;4n&quot;</code> for a quarter note)</p>
</dd>
<dt><a href="#pianoRollAPI">pianoRollAPI</a> : <code>Object</code></dt>
<dd><p>The piano roll API</p>
</dd>
</dl>
<a name="module_pixiPianoRoll"></a>
## pixiPianoRoll
JavaScript 2D WebGL / Canvas animated piano roll

**Author:** Matthew Hasbach  
**License**: MIT  
**Copyright**: Matthew Hasbach 2015

Looks like this on NPM:

image

The problem can be fixed by simply adding a line break before each header, like so:

...
</dl>

## Typedefs
...
<a name="module_pixiPianoRoll"></a>

## pixiPianoRoll
...

Here is the file from which the markdown was generated.

Enhancement: prevent handlebars from escaping

The output is markdown therefore I do not need markdown escaping html characters. When you display the README.md in a browser it doesn't make a difference, but when you look at it as plain text then all those &lt; are very distractive. At the very least add an option to disable the escaping. I also find the gfm tables to be better displayed in a browser but look horrible as plain text in emacs/vim/etc so I switched to list mode and that looks great.

Adding noEscape: true to this block forces the change. Probably best to turn it off for html output and give user option to override.

return handlebars.createCompileStream(
  options.template,
  {
    noEscape: true,
    preventIndent: true,
    data: { options: options },
    strict: false
  }
)

Occurrences where I noticed it were with strongly type Params like Promise.<string>, etc. Thanks

@category grouping should also apply in the global index

I have the following js (simple.js):

/**
 * foo!
 * @category A
 */
function foo(){}

/**
 * bar!
 * @category A
 */
function bar(){}

/**
 * baz!
 * @category B
 */
function baz(){}

/**
 * foobar!
 * @category B
 */
function foobar(){}

Running through jsdoc2md -g grouped simple.js gives me a global index in this format:

## Functions

* [foo()](#foo)
* [bar()](#bar)
* [baz()](#baz)
* [foobar()](#foobar)

I really really want those globals grouped by categories. --group-by didn't seem to have any effect. Is this not a supported feature, or am I using it wrong?

cannot use custom helpers within custom partial

Somehow I am not able to use my own registered handlebars helpers within my custom partial to render the docs.

I always get the following error:

node_modules/jsdoc2md-stats/lib/jsdoc2md-stats.js:96
        throw err
        ^
Error: Missing helper: "$"

where $ is actually a helper I wrote to enable all common logical operators.

How can I achieve a synergy between the jsdoc2md helper and my own helpers?

Support Gitiles markdown rendering

Thanks for making jsdoc-to-markdown. I love this library and it's amazing.

At Wikimedia Foundation, we host most source code repositories with Gerrit; using Gitiles as repository viewer (from Google; used for android, chromium, etc.; googlesource.com example, wikimedia.org example).

Unfortunately, Gitiles does not support the <dl> HTML extension to markdown. The result is that API.md (source) renders as API.md (gitiles) with much of the content missing:

Okay (md-fileserver) Broken (Gitiles)
rendered by md-fileserver rendered by Gitiles

I'm looking to bypass this problem with a set of custom partials, but I'm not sure where to begin and how much I'd have to override. Perhaps this could be part of jsdoc2md, e.g. via a preset of some kind. Would you accept a pull request to that end?

The resulting visual rendering might be less pleasing than the indentation of dictionary lists (which I quite like actually), but it would allow for wider compatibility.

(Upstream bug report: google/gitiles#81)

@event @type is not printed

There's no mention of type in in the output for event (output in jsdoc2md/jsdoc-to-markdown#9 suggests there once was).

Source:

/**
 * Instance of Test
 *
 * @constructor
 */
function Test () {

}

/**
 * Object event
 *
 * @event Test#event1
 * @type {object}
 * @property {boolean} isPacked - Indicates whether the snowball is tightly packed.
 */

/**
 * String event
 *
 * @event Test#event2
 * @type {string}
 */

Output:

<a name="Test"></a>
## Test
**Kind**: global class  

* [Test](#Test)
  * [new Test()](#new_Test_new)
  * ["event1"](#Test+event_event1)
  * ["event2"](#Test+event_event2)

<a name="new_Test_new"></a>
### new Test()
Instance of Test

<a name="Test+event_event1"></a>
### "event1"
Object event

**Kind**: event emitted by <code>[Test](#Test)</code>  
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| isPacked | <code>boolean</code> | Indicates whether the snowball is tightly packed. |

<a name="Test+event_event2"></a>
### "event2"
String event

**Kind**: event emitted by <code>[Test](#Test)</code>

kind should not assume "global function"

Given this input:

import { pipe, toLower, split, join, filter } from 'ramda';

const randomChars = n =>
  Math.random().toString(36).split('').slice(-(n)).join('');

const stripInvalid = str => str.replace(/[^a-zA-Z0-9-]/g, '');
const removeDashes = x => x !== '–' && x !== '-';
const exists = x => x !== undefined && x !== null;
const toString = s => exists(s) ? `${ s }` : randomChars(7);

/**
 * toSlug
 * Takes a string and converts it into a URL-safe string,
 * replacing spaces with dashes, removing capitalized letters, and
 * stripping unsafe characters out.
 *
 * @param  {(string|number)} s  A string to slugify
 * @return {string}             A slugified string
 */
const toSlug = s => pipe(
  toString,
  toLower,
  split(' '),
  filter(removeDashes),
  join('-'),
  stripInvalid
)(s);

export default toSlug;

I get the following output:


toSlug(s) ⇒ string

toSlug
Takes a string and converts it into a URL-safe string,
replacing spaces with dashes, removing capitalized letters, and
stripping unsafe characters out.

Kind: global function
Returns: string - A slugified string

Param Type Description
s string | number A string to slugify

Clearly, the kind should not be global function because the function is not global. It's scoped within a module. If I add module to the top of the file, it gets worse: Now it assumes it's a method. It's not. It's just a function. Not a global, not a method, not a class. Just a function. If I annotate it with @kind function it still says, Kind: global function.

Should support an option to turn off the index

I have one file with one class and I was getting rundant stuff like:

class x

members:
x (which linked to "class X" above"
new x() (linked to constructor below)
aMethod
anotherMethod

I used a template like this to get what I wanted:

{{heading-depth-bump~}}
{{#if (constructorHasDocs)}}{{set "isConstructor" true~}}{{>function}}{{/if~}}
{{~#each (groupByKind (children))~}}
    {{#if (equal kind "member")}}{{>member}}{{/if~}}
    {{#if (equal kind "function")}}{{>function}}{{/if~}}
    {{#if (equal kind "namespace")}}{{>namespace}}{{/if~}}
    {{#if (equal kind "constant")}}{{>constant}}{{/if~}}
    {{#if (equal kind "typedef")}}{{>typedef}}{{/if~}}
    {{#if (equal kind "event")}}{{>event}}{{/if~}}
    {{~#if (equal kind "class")~}}
        {{set "isConstructor" false~}}
        {{~#unless (equal kind "class")~}}
            {{>head~}}
        {{/unless~}}
        {{>body~}}
        {{>members~}}
    {{/if~}}
    {{#if (equal kind "module")}}{{>module}}{{/if~}}
{{/each~}}
{{heading-depth-drop~}}

It was painful to debug through a few our your modules and eventually through dmd's templates to find the right bit of handlebars markup to use.

Enhancement: Use backticks instead of `<code>` for non-html output like markdown

Its easier to read markdown with backticks vs a bunch of <code> sprawled all over the file in plain text. Again this is a matter of taste when viewing in plain text mode.

Some of the additions to link.hbs are deciding what to wrap each block in: either code or back tick ```. Also moved the wrapping in to the template deeper so the type information can all be on the same line when outputting in list format.

{{! usage: link to="namepath" html=true/false caption="optional caption"~}}

{{~#if html~}}

<code>{{#link to~}}
{{#if url~}}
<a href="{{{url}}}">{{#if ../../caption}}{{../../../caption}}{{else}}{{name}}{{/if}}</a>
{{~else~}}
{{#if ../../caption}}{{../../../caption}}{{else}}{{name}}{{/if~}}
{{/if~}}
{{/link~}}</code>

{{else~}}

`{{#link to~}}
{{#if url~}}
[{{#if ../../caption}}{{escape ../../../caption}}{{else}}{{escape name}}{{/if}}]({{{url}}})
{{~else~}}
{{#if ../../caption}}{{escape ../../../caption}}{{else}}{{escape name}}{{/if~}}
{{/if~}}
{{/link~}}`
{{~/if~}}

Also defaultValue.hbs would have to be modified. Currently it doesn't have a {{~#if html~}} so that would have to be added.

{{~#if html~}}
{{#unless (equal defaultvalue undefined)}}<code>{{#if equals}} = {{/if}}{{#if (equal type.names.[0] "string")}}{{json-stringify defaultvalue}}{{else}}{{defaultvalue}}{{/if}}</code>{{/unless}}
{{else~}}
{{#unless (equal defaultvalue undefined)}}`{{#if equals}} = {{/if}}{{#if (equal type.names.[0] "string")}}{{json-stringify defaultvalue}}{{else}}{{defaultvalue}}{{/if}}`{{/unless}}
{{~/if~}}

Respect line endings

Generated doc can end up with mixed encodings on windows.
Seems like templates (in jsdoc2md packages) are using LF encoding (as they are installed by npm and not converted by git) and windows sources (by default converted by git) use CRLF.

A bigger problem though is unnecessary diffs generated in cross-platform projects. I.e. if doc generated on Mac and later regenerated on Windows then mixed line endings would result in unnecessary diffs.

bracket-related markdown error

Say you are using the @param tag. Your parameter, name, is optional. It is of type Foo, and Foo is documented elsewhere. dmd generates the following Markdown:

[name] [Foo](#Foo)

Depending on the parser implementation (like this one), this could be a parse error. My recommendation is to generate the following code:

\[name\] [Foo](#Foo)

I have some code that does this that I can send over later, but I wanted to get your opinion before I did. It will avoid parsing issues, however it comes at the expense of human-readability.

TypeError: Cannot read property 'hash' of undefined

When trying to generate some markdown for my project,

$ jsdoc-parse tokens/*.js | dmd

I ran into an issue:

Error: Cannot read property 'hash' of undefined
TypeError: Cannot read property 'hash' of undefined
    at Object.anchorName (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/ddata/lib/ddata.js:704:12)
    at _link (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/ddata/lib/ddata.js:395:37)
    at Object.link (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/ddata/lib/ddata.js:346:21)
    at Object.eval (eval at createFunctionContext (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:221:23), <anonymous>:5:88)
    at Object.prog [as inverse] (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/runtime.js:193:15)
    at Object.<anonymous> (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/base.js:203:22)
    at Object.eval (eval at createFunctionContext (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:221:23), <anonymous>:6:32)
    at ret (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/runtime.js:159:30)
    at ret (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js:488:21)
    at Object.invokePartial (/home/jamen/.npm-global/lib/node_modules/dmd/node_modules/stream-handlebars/node_modules/handlebars/dist/cjs/handlebars/runtime.js:218:12)

Here is a gist of the json-parse string being passed in: https://gist.github.com/jamen/df318f2b5f601dfe3a5c

Here are the files being passed in: https://github.com/jamen/craze/tree/b620698eff7fffdd02cf08eb08ffdefaf0ab8828/src/tokens


This issues follows in jsdoc-to-markdown. I just thought I might post it here, since the issue seems to be originating with dmd.

Some jsdoc properties not being returned from the params function.

I am curious if it was intentional to not return some of the properties to the templates from the params function. I am personally wanting to use the optional property. It's a relatively small fix to add that one property and I could provide a PR, but while I was looking I was curious if there was a specific reason you didn't include all the possible jsdoc properties during formatting. I think that if all the properties were returned then it would make the templating much more flexible.

exported module function does not include members

/**
 * @module myModule
 */

module.exports = function foo () { ... }

exports.bar = function () { ... }
{
    "params": [],
    "name": "bar",
    "longname": "module:myModule.bar",
    "kind": "function",
    "memberof": "module:myModule",
    "scope": "static",
    "codeName": "exports.bar"
  },

exports.bar is missing from the generated docs... but seems to be parsed correctly in the output of jsdoc-parse. I'll investigate further if I have time. Exporting a class doesn't present this problem.

@see <namepath> not supported

/**
 * Both of these will link to the bar function.
 * @see {@link bar}
 * @see bar
 */
function foo() {}

docs

Input:

/** @see Class#method */

Output with jsdoc to markdown:

**See:** Class#method

Should be:

**See:** [Class#method](Class+method)

I've been looking through the ddata source trying to work out how to make this change. Not entirely sure if this is a jsdoc-parse issue or a dmd issue. Either way I'm happy to submit a PR.

Update handlebars to address three security vulnerabilities

Issue summary

I use jsdoc-to-markdown (i.e., the jsdoc2md CLI) to create API docs I can save in my repositories' GitHub wikis. It's a great tool: thanks!

I use several quality gates in my projects, including dependency checkers. Unfortunately, jsdoc-to-markdown has some nested dependencies that are out-of-date. In order to keep my projects' dependencies current, I've been shrink-wrapping them and updating the nested dependencies. Just as I was about to write a script to update my npm-shrinkwrap.json files, I thought, "Why don't I just report the issue, provide a (potential) fix, and submit a pull request?" :bowtie:

Expected Behavior

The handlebars package should be updated to version >=4.0.0 in order to address these vulnerabilities:

  1. Quoteless Attributes in Templates can lead to Content Injection
    Discovered in a nested dependency: [email protected] --> [email protected] --> [email protected]
  2. Incorrect Handling of Non-Boolean Comparisons During Minification
    Discovered in a nested dependency: [email protected] --> [email protected] --> [email protected] --> [email protected]
  3. Regular Expression Denial of Service
    Discovered in a nested dependency: [email protected] --> [email protected] --> [email protected] --> [email protected]

Current Behavior

The current version of [email protected] -- and, consequently, [email protected] -- uses a lower version of handlebars, which exposes the vulnerabilities described above.

Possible Solution

Update dmd to use [email protected], which itself has updated its nested dependencies, thereby addressing the vulnerabilities:

$ npm install --save handlebars@latest

ℹ️ I have a pull request ready, if you wanna see it

I have forked jsdoc2md/dmd with the following updates. npm test passes locally as well as on Travis-CI. I'd be happy to submit a pull request.

Vulnerability Reports

  1. See the Bithound security advisory for one of my personal repositories.
  2. See the David dependency security warning for jsdoc2md/dmd.

{@link <namepath} will break if "{@link" is at line ending

This example

// Link is generated

    /**
     * Calculates a suggestion for the region which can be used as input for
     * {@link cascadeOverlapAllWindows}. The suggested region is printed to the console and returned
     * by this method.
     */

works as expected, while the following will not generate a link, but put literally {@link cascadeOverlapAllWindows} in the output.

// No link generated

    /**
     * Calculates a suggestion for the region which can be used as input for {@link
     * cascadeOverlapAllWindows}. The suggested region is printed to the console and returned by
     * this method.
     */

In JSDoc both will generate a correct result.

Overriding default helpers does not always work

Not sure, but I think there might be a race condition when loading helpers (default and custom/overrides). My exact use case is the following:

  • create a custom helper override (e.g. linkify)
  • run the jsdoc-to-markdown with the necessary parameters

Occasionally the default helpers is used instead of the override. Not sure whether I should post this here or in jsdoc-to-markdown, but seeing that it concerns a dmd helper I decide this would be a better place.

Add note on how to migrate to V2

Hello! Nice move to sync API. I had to dig a bit to understand we had to move from:

    let dmdStream = dmd({
      template: ...,
      helper: ['./scripts/helpers']
    });

    dmdStream.pipe(fs.createWriteStream('file.md')));
    dmdStream.end(JSON.stringify(data));

to:

    const fileContent = dmd(data, {
      template: ...,
      helper: ['./scripts/helpers']
    });

    const filePath = 'file.md';
    fs.writeFile(filePath, fileContent);

Maybe worth adding to the readme. As a general rule, we try to have CHANGELOG.md, nice and simple.

Pipes aren't escaped in param tables

If a pipe is enclosed in a param type, e.g. {number|string}, it will be treated as a delimiter for the table, and the types will be split into different cells. You can see this here: https://github.com/jsdoc2md/jsdoc-to-markdown/blob/master/docs/API.md (jsdoc2md.render() > options.plugin)

Looks like this was fixed before by replacing \| with &#124;, but I guess Github changed how they parse Markdown. I think if the &#124; is enclosed in the <code> tag, it will render properly: https://stackoverflow.com/questions/17319940/how-to-escape-a-pipe-char-in-a-code-statement-in-a-markdown-table/17320389#17320389.

Looked into fixing the partial myself, but wasn't confident I could do it without breaking other parts of the template...

Class function documentation?

I want my class instance static functions to show up in the output, but even though they are parsed correctly, they aren't output.

Is there something I'm missing or is this expected?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.