Skip to content

Commit 4c66fb1

Browse files
authored
feat(markdown): Add table of contents support for Markdown mode (#645)
Adds a new option, `--no-markdown-toc`, to turn off Table of Contents generation. Table of contents are now generated by default with markdown output, including through the `readme` command. Fixes #220
1 parent 2ae5d8f commit 4c66fb1

File tree

117 files changed

+6571
-161
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+6571
-161
lines changed

docs/NODE_API.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
22

3+
### Table of Contents
4+
5+
- [build](#build)
6+
- [buildSync](#buildsync)
7+
- [lint](#lint)
8+
- [formats](#formats)
9+
- [formats.html](#formatshtml)
10+
- [formats.markdown](#formatsmarkdown)
11+
- [formats.json](#formatsjson)
12+
313
## build
414

515
Generate JavaScript documentation as a list of parsed JSDoc

lib/commands/build.js

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ module.exports.builder = extend({},
2626
default: 'json',
2727
choices: ['json', 'md', 'remark', 'html']
2828
},
29+
'no-markdown-toc': {
30+
describe: 'include a table of contents in markdown output',
31+
default: 'stdout',
32+
type: 'boolean'
33+
},
2934
output: {
3035
describe: 'output location. omit for stdout, otherwise is a filename ' +
3136
'for single-file outputs and a directory name for multi-file outputs like html',
@@ -66,6 +71,7 @@ module.exports.handler = function build(argv, callback) {
6671
version: argv['project-version'] || (argv.package || {}).version,
6772
theme: argv.theme,
6873
paths: argv.paths,
74+
'no-markdown-toc': argv['no-markdown-toc'],
6975
hljs: argv.hljs || {}
7076
};
7177

lib/commands/readme.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ module.exports.builder = {
4242
example: 'documentation readme index.js -s "API Docs" --github'
4343
};
4444

45+
function noop() {}
46+
4547
/**
4648
* Insert API documentation into a Markdown readme
4749
* @private
@@ -53,8 +55,7 @@ module.exports.handler = function readme(argv) {
5355
argv = sharedOptions.expandInputs(argv);
5456
argv.format = 'remark';
5557
/* eslint no-console: 0 */
56-
var log = argv.q ? function () {}
57-
: console.log.bind(console, '[documentation-readme] ');
58+
var log = argv.q ? noop : console.log.bind(console, '[documentation-readme] ');
5859
var readmeFile = argv['readme-file'];
5960

6061
build.handler(argv, onAst);

lib/output/markdown.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
var remark = require('remark'),
4-
toc = require('remark-toc'),
54
markdownAST = require('./markdown_ast');
65

76
/**
@@ -26,9 +25,7 @@ var remark = require('remark'),
2625
* });
2726
*/
2827
module.exports = function (comments, options, callback) {
29-
var processor = remark().use(toc);
3028
markdownAST(comments, options, function (err, ast) {
31-
var processedAST = processor.run(ast);
32-
return callback(null, processor.stringify(processedAST));
29+
return callback(null, remark().stringify(ast));
3330
});
3431
};

lib/output/markdown_ast.js

+22-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
var u = require('unist-builder'),
2+
remark = require('remark'),
3+
toc = require('remark-toc'),
24
hljs = require('highlight.js'),
35
GithubSlugger = require('github-slugger'),
46
createLinkerStack = require('./util/linker_stack'),
@@ -14,7 +16,7 @@ var u = require('unist-builder'),
1416
* @param {Function} callback called with AST
1517
* @returns {undefined} calls callback
1618
*/
17-
function commentsToAST(comments, options, callback) {
19+
function markdownAST(comments, options, callback) {
1820

1921
// Configure code highlighting
2022
var hljsOptions = (options || {}).hljs || {},
@@ -33,6 +35,10 @@ function commentsToAST(comments, options, callback) {
3335
u('html', '<!-- Generated by documentation.js. Update this documentation by updating the source code. -->')
3436
];
3537

38+
var tableOfContentsHeading = [
39+
u('heading', { depth: 3 }, [u('text', 'Table of Contents')])
40+
];
41+
3642
/**
3743
* Generate an AST chunk for a comment at a given depth: this is
3844
* split from the main function to handle hierarchially nested comments
@@ -202,10 +208,20 @@ function commentsToAST(comments, options, callback) {
202208
.filter(Boolean);
203209
}
204210

205-
return callback(null, rerouteLinks(linkerStack.link,
206-
u('root', generatorComment.concat(comments.reduce(function (memo, comment) {
207-
return memo.concat(generate(2, comment));
208-
}, [])))));
211+
var root = rerouteLinks(linkerStack.link,
212+
u('root', generatorComment
213+
.concat(options['no-markdown-toc'] ? [] : tableOfContentsHeading)
214+
.concat(comments.reduce(function (memo, comment) {
215+
return memo.concat(generate(2, comment));
216+
}, []))));
217+
218+
if (!options['no-markdown-toc']) {
219+
return remark().use(toc, {
220+
tight: true
221+
}).run(root, callback);
222+
}
223+
224+
return callback(null, root);
209225
}
210226

211-
module.exports = commentsToAST;
227+
module.exports = markdownAST;

test/fixture/auto_lang_hljs/multilanguage.output.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
22

3+
### Table of Contents
4+
5+
- [multilanguage.input](#multilanguageinput)
6+
37
## multilanguage.input
48

59
**Extends Foo, Bar**

test/fixture/boolean-literal-type.output.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
22

3+
### Table of Contents
4+
5+
- [f](#f)
6+
37
## f
48

59
**Parameters**

test/fixture/boolean-literal-type.output.md.json

+57-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,53 @@
55
"type": "html",
66
"value": "<!-- Generated by documentation.js. Update this documentation by updating the source code. -->"
77
},
8+
{
9+
"depth": 3,
10+
"type": "heading",
11+
"children": [
12+
{
13+
"type": "text",
14+
"value": "Table of Contents"
15+
}
16+
],
17+
"data": {
18+
"id": "table-of-contents",
19+
"htmlAttributes": {
20+
"id": "table-of-contents"
21+
},
22+
"hProperties": {
23+
"id": "table-of-contents"
24+
}
25+
}
26+
},
27+
{
28+
"type": "list",
29+
"ordered": false,
30+
"children": [
31+
{
32+
"type": "listItem",
33+
"loose": false,
34+
"children": [
35+
{
36+
"type": "paragraph",
37+
"children": [
38+
{
39+
"type": "link",
40+
"title": null,
41+
"url": "#f",
42+
"children": [
43+
{
44+
"type": "text",
45+
"value": "f"
46+
}
47+
]
48+
}
49+
]
50+
}
51+
]
52+
}
53+
]
54+
},
855
{
956
"depth": 2,
1057
"type": "heading",
@@ -13,7 +60,16 @@
1360
"type": "text",
1461
"value": "f"
1562
}
16-
]
63+
],
64+
"data": {
65+
"id": "f",
66+
"htmlAttributes": {
67+
"id": "f"
68+
},
69+
"hProperties": {
70+
"id": "f"
71+
}
72+
}
1773
},
1874
{
1975
"type": "strong",

test/fixture/class.config.output.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
22

3+
### Table of Contents
4+
5+
- [MyClass](#myclass)
6+
- [getFoo](#getfoo)
7+
- [getUndefined](#getundefined)
8+
- [Hello](#hello)
9+
310
## MyClass
411

512
This is my class, a demo thing.

test/fixture/class.output.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
22

3+
### Table of Contents
4+
5+
- [MyClass](#myclass)
6+
- [getFoo](#getfoo)
7+
- [getUndefined](#getundefined)
8+
39
## MyClass
410

511
This is my class, a demo thing.

0 commit comments

Comments
 (0)