diff --git a/lib/index.js b/lib/index.js index a409e61..6b09044 100644 --- a/lib/index.js +++ b/lib/index.js @@ -9,7 +9,7 @@ var contents = require('./contents') function toc(node, options) { var settings = options || {} var heading = settings.heading ? toExpression(settings.heading) : null - var result = search(node, heading, settings.maxDepth || 6) + var result = search(node, heading, settings) var map = result.map result.map = map.length === 0 ? null : contents(map, settings.tight) diff --git a/lib/search.js b/lib/search.js index 99a7158..17c1b7b 100644 --- a/lib/search.js +++ b/lib/search.js @@ -4,15 +4,18 @@ module.exports = search var toString = require('mdast-util-to-string') var visit = require('unist-util-visit') +var is = require('unist-util-is') var slugs = require('github-slugger')() var HEADING = 'heading' // Search a node for a location. -function search(root, expression, maxDepth) { +function search(root, expression, settings) { var length = root.children.length var depth = null var lookingForToc = expression !== null + var maxDepth = settings.maxDepth || 6 + var parents = settings.parents || root var map = [] var headingIndex var closingIndex @@ -43,7 +46,7 @@ function search(root, expression, maxDepth) { var value = toString(child) var id = child.data && child.data.hProperties && child.data.hProperties.id - if (parent !== root) { + if (!is(parents, parent)) { return } diff --git a/package.json b/package.json index fd23cc1..ec81b7c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "github-slugger": "^1.1.1", "mdast-util-to-string": "^1.0.2", + "unist-util-is": "^2.1.2", "unist-util-visit": "^1.1.0" }, "devDependencies": { diff --git a/readme.md b/readme.md index 23d43ca..894b1d1 100644 --- a/readme.md +++ b/readme.md @@ -60,6 +60,7 @@ If no `heading` is specified, creates a table of contents for all headings in Links to headings are based on GitHub’s style. Only top-level headings (those not in blockquotes or lists), are used. +(Change this default behavior by using option `parents` as described below) The given node is not modified. ##### `options` @@ -79,6 +80,28 @@ This is inclusive, thus, when set to `3`, level three headings, are included Whether to compile list-items tightly (`boolean?`, default: `false`). +###### `options.parents` + +Allows headings to be children of certain node types. +Internally, it uses +[unist-util-is](https://github.com/syntax-tree/unist-util-is) to check. +Hence all types that can be passed in as first parameter can be used here, +including `Function`, `string`, `Object` and `Array.`. +Check +[documentation](https://github.com/syntax-tree/unist-util-is#readme) +for details. +(default: the first parameter `node`, which only allows top-level headings) + +Example: + +```json +{ + "parents": ["root", "blockquote"] +} +``` + +This would allow headings under either `root` or `blockquote` to be used. + ##### Returns An object representing the table of contents. diff --git a/test/fixtures/deep-headings-with-config/config.json b/test/fixtures/deep-headings-with-config/config.json new file mode 100644 index 0000000..4f9487e --- /dev/null +++ b/test/fixtures/deep-headings-with-config/config.json @@ -0,0 +1,3 @@ +{ + "parents": ["root", "blockquote"] +} diff --git a/test/fixtures/deep-headings-with-config/input.md b/test/fixtures/deep-headings-with-config/input.md new file mode 100644 index 0000000..e41f57a --- /dev/null +++ b/test/fixtures/deep-headings-with-config/input.md @@ -0,0 +1,11 @@ +# Something if + +## Something else + +Text. + +> ## heading in a blockquote + +* ## heading in a list + +# Something iffi diff --git a/test/fixtures/deep-headings-with-config/output.json b/test/fixtures/deep-headings-with-config/output.json new file mode 100644 index 0000000..e64a6cf --- /dev/null +++ b/test/fixtures/deep-headings-with-config/output.json @@ -0,0 +1,110 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "spread": true, + "children": [ + { + "type": "listItem", + "loose": true, + "spread": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "spread": false, + "children": [ + { + "type": "listItem", + "loose": false, + "spread": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "spread": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#heading-in-a-blockquote", + "children": [ + { + "type": "text", + "value": "heading in a blockquote" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "spread": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +}