diff --git a/.remarkrc b/.remarkrc index 1b05294..8c833ff 100644 --- a/.remarkrc +++ b/.remarkrc @@ -5,7 +5,6 @@ "lint", "github", "usage", - "slug", "validate-links" ], "settings": { diff --git a/README.md b/README.md index b2cffda..51e66e5 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ npm install remark-toc **mdast-util-toc** is also available as an AMD, CommonJS, and globals module, [uncompressed and compressed][releases]. +## Usage + Dependencies: ```javascript @@ -20,10 +22,10 @@ var remark = require('remark'); var toc = require('mdast-util-toc'); ``` -Transform: +Parse: ```javascript -var input = remark().parse([ +var node = remark().parse([ '# Alpha', '', '## Bravo', @@ -33,11 +35,23 @@ var input = remark().parse([ '## Delta', '' ].join('\n')); +``` + +TOC: + +```javascript +var result = toc(node); +``` -toc(input)); +Yields: -// { map: [ { type: 'list', ordered: false, children: [{...}] } ], -// index: -1 } +```js +{ index: null, + endIndex: null, + map: + { type: 'list', + ordered: false, + children: [ { type: 'listItem', loose: true, children: [Object] } ] } } ``` ## API @@ -46,14 +60,17 @@ toc(input)); Generate a Table of Contents from a Markdown document. -* If specified, looks for the first heading containing the `heading` option - (case insensitive, supports alt/title attributes for links and images too); +* If specified, looks for the first heading containing the `heading` + option (case insensitive, supports alt/title attributes for links + and images too), and returns a table of contents for all following + headings. -* Removes all following contents until an equal or higher heading is found; +* If no `heading` is specified, creates a table of contents for all + headings in `node`. -* Inserts a list representation of the hierarchy of following headings; - -* Adds links to following headings, using the same slugs as GitHub. +Links to headings are based on GitHub’s style. Only top-level headings +(those not in blockquotes or lists), are used. The given node is not +modified. #### `options` @@ -68,6 +85,25 @@ Generate a Table of Contents from a Markdown document. * `tight` (`boolean?`, default: `false`) — Whether to compile list-items tightly. +#### Returns + +An object with the following properties: + +* `index` (`number?`) + — Position of the `heading` in `node`. `-1` if no heading + was found, `null` if no heading was given; + +* `endIndex` (`number?`) + — Position of the last node after `heading` before the TOC starts. + `-1` if no heading was found, `null` if no heading was given, + same as `index` if there are no nodes between `heading` and the + first heading in the TOC; + +* `map` (`Node?`) + — List node representing the generated table of contents. + `null` if no table of contents could be created, either because + no `heading` didn’t exist, or no following headings were found. + ## License [MIT][license] © [Jonathan Haines][author] diff --git a/example.js b/example.js index 57084f1..b393366 100644 --- a/example.js +++ b/example.js @@ -2,8 +2,8 @@ var remark = require('remark'); var toc = require('./index.js'); -// Transform: -var input = remark().parse([ +// Parse: +var node = remark().parse([ '# Alpha', '', '## Bravo', @@ -14,5 +14,8 @@ var input = remark().parse([ '' ].join('\n')); +// TOC: +var result = toc(node); + // Yields: -console.log('markdown', toc(input)); +console.log('js', require('util').inspect(result, {depth: 3})); diff --git a/lib/index.js b/lib/index.js index 1ce77b3..62a52cc 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,38 +7,32 @@ */ /* Expose. */ -module.exports = attacher; +module.exports = toc; /* Dependencies */ -var remark = require('remark'); -var slug = require('remark-slug'); var toExpression = require('./to-expression'); var search = require('./search'); var contents = require('./contents'); /** - * Attacher. + * Get a TOC representation of `node`. * * @param {Mdast} node - MDAST. * @param {Object} options - Configuration. * @return {Array} - TOC Markdown. */ -function attacher(node, options) { +function toc(node, options) { var settings = options || {}; var heading = settings.heading ? toExpression(settings.heading) : null; - var depth = settings.maxDepth || 6; - var tight = settings.tight; + var result = search(node, heading, settings.maxDepth || 6); + var map = result.map; - var processor = remark().use(slug); - var tree = processor.run(node); - var result = search(tree, heading, depth); + result.map = map.length ? contents(map, settings.tight) : null; - if (result.index === null || !result.map.length) { - return result; + /* No given heading */ + if (!heading) { + result.index = result.endIndex = null; } - return { - map: [contents(result.map, tight)], - index: result.index - }; + return result; } diff --git a/lib/insert.js b/lib/insert.js index 70ecd6a..72ae02f 100644 --- a/lib/insert.js +++ b/lib/insert.js @@ -6,103 +6,99 @@ * @fileoverview Generate a Table of Contents (TOC) from a given Markdown file. */ - /* Expose. */ - module.exports = insert; - - /* Dependencies */ - var listItem = require('./list-item'); - var list = require('./list'); - - /* Constants */ - var LIST = 'list'; - var LIST_ITEM = 'listItem'; - var PARAGRAPH = 'paragraph'; - var LINK = 'link'; - var TEXT = 'text'; - - /** - * Insert a `node` into a `parent`. - * - * @param {Object} node - `node` to insert. - * @param {Object} parent - Parent of `node`. - * @param {boolean?} [tight] - Prefer tight list-items. - * @return {undefined} - */ - function insert(node, parent, tight) { - var children = parent.children; - var length = children.length; - var last = children[length - 1]; - var isLoose = false; - var index; - var item; - - if (node.depth === 1) { - item = listItem(); - - item.children.push({ - type: PARAGRAPH, - children: [ - { - type: LINK, - title: null, - url: '#' + node.id, - children: [ - { - type: TEXT, - value: node.value - } - ] - } - ] - }); - - children.push(item); - } else if (last && last.type === LIST_ITEM) { - insert(node, last, tight); - } else if (last && last.type === LIST) { - node.depth--; - - insert(node, last); - } else if (parent.type === LIST) { - item = listItem(); - - insert(node, item); - - children.push(item); - } else { - item = list(); - node.depth--; - - insert(node, item); - - children.push(item); - } - - /* - * Properly style list-items with new lines. - */ - - if (parent.type === LIST_ITEM) { - parent.loose = tight ? false : children.length > 1; - } else { - if (tight) { - isLoose = false; - } else { - index = -1; - - while (++index < length) { - if (children[index].loose) { - isLoose = true; - - break; - } - } - } - - index = -1; - - while (++index < length) { - children[index].loose = isLoose; - } - } - } +/* Expose. */ +module.exports = insert; + +/* Dependencies */ +var listItem = require('./list-item'); +var list = require('./list'); + +/* Constants */ +var LIST = 'list'; +var LIST_ITEM = 'listItem'; +var PARAGRAPH = 'paragraph'; +var LINK = 'link'; +var TEXT = 'text'; + +/** +* Insert a `node` into a `parent`. +* +* @param {Object} node - `node` to insert. +* @param {Object} parent - Parent of `node`. +* @param {boolean?} [tight] - Prefer tight list-items. +* @return {undefined} +*/ +function insert(node, parent, tight) { + var children = parent.children; + var length = children.length; + var last = children[length - 1]; + var isLoose = false; + var index; + var item; + + if (node.depth === 1) { + item = listItem(); + + item.children.push({ + type: PARAGRAPH, + children: [{ + type: LINK, + title: null, + url: '#' + node.id, + children: [{ + type: TEXT, + value: node.value + }] + }] + }); + + children.push(item); + } else if (last && last.type === LIST_ITEM) { + insert(node, last, tight); + } else if (last && last.type === LIST) { + node.depth--; + + insert(node, last); + } else if (parent.type === LIST) { + item = listItem(); + + insert(node, item); + + children.push(item); + } else { + item = list(); + node.depth--; + + insert(node, item); + + children.push(item); + } + + /* + * Properly style list-items with new lines. + */ + + if (parent.type === LIST_ITEM) { + parent.loose = tight ? false : children.length > 1; + } else { + if (tight) { + isLoose = false; + } else { + index = -1; + + while (++index < length) { + if (children[index].loose) { + isLoose = true; + + break; + } + } + } + + index = -1; + + while (++index < length) { + children[index].loose = isLoose; + } + } +} diff --git a/lib/list-item.js b/lib/list-item.js index 9e10eb9..c5e5005 100644 --- a/lib/list-item.js +++ b/lib/list-item.js @@ -6,21 +6,21 @@ * @fileoverview Generate a Table of Contents (TOC) from a given Markdown file. */ - /* Expose. */ - module.exports = listItem; +/* Expose. */ +module.exports = listItem; - /* Constants */ - var LIST_ITEM = 'listItem'; +/* Constants */ +var LIST_ITEM = 'listItem'; - /** - * Create a list item. - * - * @return {Object} - List-item node. - */ - function listItem() { - return { - type: LIST_ITEM, - loose: false, - children: [] - }; - } +/** +* Create a list item. +* +* @return {Object} - List-item node. +*/ +function listItem() { + return { + type: LIST_ITEM, + loose: false, + children: [] + }; +} diff --git a/lib/list.js b/lib/list.js index e19576e..396e132 100644 --- a/lib/list.js +++ b/lib/list.js @@ -6,21 +6,21 @@ * @fileoverview Generate a Table of Contents (TOC) from a given Markdown file. */ - /* Expose. */ - module.exports = list; +/* Expose. */ +module.exports = list; - /* Constants */ - var LIST = 'list'; +/* Constants */ +var LIST = 'list'; - /** - * Create a list. - * - * @return {Object} - List node. - */ - function list() { - return { - type: LIST, - ordered: false, - children: [] - }; - } +/** +* Create a list. +* +* @return {Object} - List node. +*/ +function list() { + return { + type: LIST, + ordered: false, + children: [] + }; +} diff --git a/lib/search.js b/lib/search.js index 47ebf44..d423d24 100644 --- a/lib/search.js +++ b/lib/search.js @@ -11,6 +11,8 @@ module.exports = search; /* Dependencies */ var toString = require('mdast-util-to-string'); +var visit = require('unist-util-visit'); +var slugs = require('github-slugger')(); var isClosingHeading = require('./is-closing-heading'); var isOpeningHeading = require('./is-opening-heading'); @@ -27,28 +29,32 @@ var HEADING = 'heading'; * @return {Object} - Results. */ function search(root, expression, maxDepth) { - var index = -1; var length = root.children.length; var depth = null; - var lookingForToc = true && expression !== null; + var lookingForToc = expression !== null; var map = []; - var child; var headingIndex; var closingIndex; - var value; if (!lookingForToc) { headingIndex = -1; } - while (++index < length) { - child = root.children[index]; + slugs.reset(); - if (child.type !== HEADING) { - continue; - } + /* + * Visit all headings in `root`. + * We `slug` all headings (to account for duplicates), + * but only create a TOC from top-level headings. + */ + + visit(root, HEADING, function (child, index, parent) { + var value = toString(child); + var id = slugs.slug(value); - value = toString(child); + if (parent !== root) { + return; + } if (lookingForToc) { if (isClosingHeading(child, depth)) { @@ -66,25 +72,23 @@ function search(root, expression, maxDepth) { map.push({ depth: child.depth, value: value, - id: child.data.htmlAttributes.id + id: id }); } - } + }); - if (headingIndex) { - if (!closingIndex) { - closingIndex = length + 1; - } - - /* - * Remove current TOC. - */ + if (headingIndex && !closingIndex) { + closingIndex = length + 1; + } - root.children.splice(headingIndex, closingIndex - headingIndex); + if (headingIndex === undefined) { + headingIndex = closingIndex = -1; + map = []; } return { - index: headingIndex || null, + index: headingIndex, + endIndex: closingIndex, map: map }; } diff --git a/package.json b/package.json index fe5a09e..3ef01bb 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ ], "scripts": { "build-md": "remark . --quiet --frail", - "build-bundle": "browserify index.js --no-builtins -s remarkTOC > mdast-util-toc.js", + "build-bundle": "browserify index.js --no-builtins -s mdastUtilTOC > mdast-util-toc.js", "build-mangle": "esmangle mdast-util-toc.js > mdast-util-toc.min.js", "build": "npm run build-md && npm run build-bundle && npm run build-mangle", "lint": "xo index.js test", @@ -34,8 +34,9 @@ "bugs": "https://github.com/barrythepenguin/mdast-util-toc/issues", "license": "MIT", "dependencies": { + "github-slugger": "^1.1.1", "mdast-util-to-string": "^1.0.2", - "remark-slug": "^4.2.0" + "unist-util-visit": "^1.1.0" }, "devDependencies": { "browserify": "^13.0.1", diff --git a/test/fixtures/custom-heading/output.json b/test/fixtures/custom-heading/output.json new file mode 100644 index 0000000..bbf2d32 --- /dev/null +++ b/test/fixtures/custom-heading/output.json @@ -0,0 +1,104 @@ +{ + "index": 2, + "endIndex": 2, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/custom-heading/output.md b/test/fixtures/custom-heading/output.md deleted file mode 100644 index 40997b9..0000000 --- a/test/fixtures/custom-heading/output.md +++ /dev/null @@ -1,6 +0,0 @@ -- [Something if](#something-if) - - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) - -- [Something iffi](#something-iffi) diff --git a/test/fixtures/deep-headings/input.md b/test/fixtures/deep-headings/input.md new file mode 100644 index 0000000..e41f57a --- /dev/null +++ b/test/fixtures/deep-headings/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/output.json b/test/fixtures/deep-headings/output.json new file mode 100644 index 0000000..e493807 --- /dev/null +++ b/test/fixtures/deep-headings/output.json @@ -0,0 +1,82 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/empty-headings/output.json b/test/fixtures/empty-headings/output.json new file mode 100644 index 0000000..0393ea9 --- /dev/null +++ b/test/fixtures/empty-headings/output.json @@ -0,0 +1,5 @@ +{ + "index": null, + "endIndex": null, + "map": null +} diff --git a/test/fixtures/empty-headings/output.md b/test/fixtures/empty-headings/output.md deleted file mode 100644 index 8b13789..0000000 --- a/test/fixtures/empty-headings/output.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/image-in-link-in-heading/output.json b/test/fixtures/image-in-link-in-heading/output.json new file mode 100644 index 0000000..51696d6 --- /dev/null +++ b/test/fixtures/image-in-link-in-heading/output.json @@ -0,0 +1,104 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/image-in-link-in-heading/output.md b/test/fixtures/image-in-link-in-heading/output.md deleted file mode 100644 index 40997b9..0000000 --- a/test/fixtures/image-in-link-in-heading/output.md +++ /dev/null @@ -1,6 +0,0 @@ -- [Something if](#something-if) - - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) - -- [Something iffi](#something-iffi) diff --git a/test/fixtures/maximum-depth-1/output.json b/test/fixtures/maximum-depth-1/output.json new file mode 100644 index 0000000..d3c9174 --- /dev/null +++ b/test/fixtures/maximum-depth-1/output.json @@ -0,0 +1,32 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#alpha", + "children": [ + { + "type": "text", + "value": "Alpha" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/maximum-depth-1/output.md b/test/fixtures/maximum-depth-1/output.md deleted file mode 100644 index ab807db..0000000 --- a/test/fixtures/maximum-depth-1/output.md +++ /dev/null @@ -1 +0,0 @@ -- [Alpha](#alpha) diff --git a/test/fixtures/maximum-depth-3/output.json b/test/fixtures/maximum-depth-3/output.json new file mode 100644 index 0000000..dec6535 --- /dev/null +++ b/test/fixtures/maximum-depth-3/output.json @@ -0,0 +1,88 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#alpha", + "children": [ + { + "type": "text", + "value": "Alpha" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#bravo", + "children": [ + { + "type": "text", + "value": "Bravo" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#charlie", + "children": [ + { + "type": "text", + "value": "Charlie" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/maximum-depth-3/output.md b/test/fixtures/maximum-depth-3/output.md deleted file mode 100644 index cb6ae17..0000000 --- a/test/fixtures/maximum-depth-3/output.md +++ /dev/null @@ -1,5 +0,0 @@ -- [Alpha](#alpha) - - - [Bravo](#bravo) - - - [Charlie](#charlie) diff --git a/test/fixtures/maximum-depth-6/output.json b/test/fixtures/maximum-depth-6/output.json new file mode 100644 index 0000000..77b8a13 --- /dev/null +++ b/test/fixtures/maximum-depth-6/output.json @@ -0,0 +1,172 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#alpha", + "children": [ + { + "type": "text", + "value": "Alpha" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#bravo", + "children": [ + { + "type": "text", + "value": "Bravo" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#charlie", + "children": [ + { + "type": "text", + "value": "Charlie" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#delta", + "children": [ + { + "type": "text", + "value": "Delta" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#echo", + "children": [ + { + "type": "text", + "value": "Echo" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#foxtrot", + "children": [ + { + "type": "text", + "value": "Foxtrot" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/maximum-depth-6/output.md b/test/fixtures/maximum-depth-6/output.md deleted file mode 100644 index cbc5247..0000000 --- a/test/fixtures/maximum-depth-6/output.md +++ /dev/null @@ -1,11 +0,0 @@ -- [Alpha](#alpha) - - - [Bravo](#bravo) - - - [Charlie](#charlie) - - - [Delta](#delta) - - - [Echo](#echo) - - - [Foxtrot](#foxtrot) diff --git a/test/fixtures/missing-content/output.json b/test/fixtures/missing-content/output.json new file mode 100644 index 0000000..0393ea9 --- /dev/null +++ b/test/fixtures/missing-content/output.json @@ -0,0 +1,5 @@ +{ + "index": null, + "endIndex": null, + "map": null +} diff --git a/test/fixtures/missing-content/output.md b/test/fixtures/missing-content/output.md deleted file mode 100644 index 8b13789..0000000 --- a/test/fixtures/missing-content/output.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/missing-heading/output.json b/test/fixtures/missing-heading/output.json new file mode 100644 index 0000000..1787c6f --- /dev/null +++ b/test/fixtures/missing-heading/output.json @@ -0,0 +1,5 @@ +{ + "index": -1, + "endIndex": -1, + "map": null +} diff --git a/test/fixtures/missing-heading/output.md b/test/fixtures/missing-heading/output.md deleted file mode 100644 index 8b13789..0000000 --- a/test/fixtures/missing-heading/output.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/normal-literal-dashes/output.json b/test/fixtures/normal-literal-dashes/output.json new file mode 100644 index 0000000..234e1b9 --- /dev/null +++ b/test/fixtures/normal-literal-dashes/output.json @@ -0,0 +1,82 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#rules", + "children": [ + { + "type": "text", + "value": "Rules" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#foo-bar-baz", + "children": [ + { + "type": "text", + "value": "Foo-bar-baz" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#alpha-bravo-charlie", + "children": [ + { + "type": "text", + "value": "Alpha-bravo-charlie" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/normal-literal-dashes/output.md b/test/fixtures/normal-literal-dashes/output.md deleted file mode 100644 index 1763fb3..0000000 --- a/test/fixtures/normal-literal-dashes/output.md +++ /dev/null @@ -1,5 +0,0 @@ -- [Rules](#rules) - - - [Foo-bar-baz](#foo-bar-baz) - -- [Alpha-bravo-charlie](#alpha-bravo-charlie) diff --git a/test/fixtures/normal-nesting-inverted/output.json b/test/fixtures/normal-nesting-inverted/output.json new file mode 100644 index 0000000..485139f --- /dev/null +++ b/test/fixtures/normal-nesting-inverted/output.json @@ -0,0 +1,116 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/normal-nesting-inverted/output.md b/test/fixtures/normal-nesting-inverted/output.md deleted file mode 100644 index fd57d44..0000000 --- a/test/fixtures/normal-nesting-inverted/output.md +++ /dev/null @@ -1,7 +0,0 @@ -- - [Something if](#something-if) - -- [Something else](#something-else) - - - [Something elsefi](#something-elsefi) - -- [Something iffi](#something-iffi) diff --git a/test/fixtures/normal-singular/output.json b/test/fixtures/normal-singular/output.json new file mode 100644 index 0000000..51696d6 --- /dev/null +++ b/test/fixtures/normal-singular/output.json @@ -0,0 +1,104 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/normal-singular/output.md b/test/fixtures/normal-singular/output.md deleted file mode 100644 index 40997b9..0000000 --- a/test/fixtures/normal-singular/output.md +++ /dev/null @@ -1,6 +0,0 @@ -- [Something if](#something-if) - - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) - -- [Something iffi](#something-iffi) diff --git a/test/fixtures/normal-toc/output.json b/test/fixtures/normal-toc/output.json new file mode 100644 index 0000000..51696d6 --- /dev/null +++ b/test/fixtures/normal-toc/output.json @@ -0,0 +1,104 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/normal-toc/output.md b/test/fixtures/normal-toc/output.md deleted file mode 100644 index 40997b9..0000000 --- a/test/fixtures/normal-toc/output.md +++ /dev/null @@ -1,6 +0,0 @@ -- [Something if](#something-if) - - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) - -- [Something iffi](#something-iffi) diff --git a/test/fixtures/normal/output.json b/test/fixtures/normal/output.json new file mode 100644 index 0000000..51696d6 --- /dev/null +++ b/test/fixtures/normal/output.json @@ -0,0 +1,104 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/normal/output.md b/test/fixtures/normal/output.md deleted file mode 100644 index 40997b9..0000000 --- a/test/fixtures/normal/output.md +++ /dev/null @@ -1,6 +0,0 @@ -- [Something if](#something-if) - - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) - -- [Something iffi](#something-iffi) diff --git a/test/fixtures/slug-for-images-and-links/output.json b/test/fixtures/slug-for-images-and-links/output.json new file mode 100644 index 0000000..b5d1555 --- /dev/null +++ b/test/fixtures/slug-for-images-and-links/output.json @@ -0,0 +1,104 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": true, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#another-title", + "children": [ + { + "type": "text", + "value": "another title" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/slug-for-images-and-links/output.md b/test/fixtures/slug-for-images-and-links/output.md deleted file mode 100644 index 394dec0..0000000 --- a/test/fixtures/slug-for-images-and-links/output.md +++ /dev/null @@ -1,6 +0,0 @@ -- [Something if](#something-if) - - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) - -- [another title](#another-title) diff --git a/test/fixtures/tight/output.json b/test/fixtures/tight/output.json new file mode 100644 index 0000000..5ce4d91 --- /dev/null +++ b/test/fixtures/tight/output.json @@ -0,0 +1,104 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-if", + "children": [ + { + "type": "text", + "value": "Something if" + } + ] + } + ] + }, + { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-else", + "children": [ + { + "type": "text", + "value": "Something else" + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-elsefi", + "children": [ + { + "type": "text", + "value": "Something elsefi" + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#something-iffi", + "children": [ + { + "type": "text", + "value": "Something iffi" + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/tight/output.md b/test/fixtures/tight/output.md deleted file mode 100644 index e43c925..0000000 --- a/test/fixtures/tight/output.md +++ /dev/null @@ -1,4 +0,0 @@ -- [Something if](#something-if) - - [Something else](#something-else) - - [Something elsefi](#something-elsefi) -- [Something iffi](#something-iffi) diff --git a/test/fixtures/unicode/output.json b/test/fixtures/unicode/output.json new file mode 100644 index 0000000..346c047 --- /dev/null +++ b/test/fixtures/unicode/output.json @@ -0,0 +1,32 @@ +{ + "index": null, + "endIndex": null, + "map": { + "type": "list", + "ordered": false, + "children": [ + { + "type": "listItem", + "loose": false, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "#i--unicode", + "children": [ + { + "type": "text", + "value": "I ♥ unicode." + } + ] + } + ] + } + ] + } + ] + } +} diff --git a/test/fixtures/unicode/output.md b/test/fixtures/unicode/output.md deleted file mode 100644 index 0a99c35..0000000 --- a/test/fixtures/unicode/output.md +++ /dev/null @@ -1 +0,0 @@ -- [I ♥ unicode.](#i--unicode) diff --git a/test/index.js b/test/index.js index 44f00ee..2244182 100644 --- a/test/index.js +++ b/test/index.js @@ -13,8 +13,6 @@ var ROOT = join(__dirname, 'fixtures'); var fixtures = fs.readdirSync(ROOT); -var compiler = new remark.Compiler(); - test('mdast-util-toc()', function (t) { t.is(typeof toc, 'function', 'should be a function'); @@ -30,18 +28,15 @@ test('Fixtures', function (t) { return filepath.indexOf('.') !== 0; }).forEach(function (fixture) { var filepath = join(ROOT, fixture); - var output = read(join(filepath, 'output.md'), 'utf-8'); + var output = JSON.parse(read(join(filepath, 'output.json'), 'utf8')); var input = remark().parse(read(join(filepath, 'input.md'), 'utf-8')); var config = join(filepath, 'config.json'); var result; config = exists(config) ? JSON.parse(read(config, 'utf-8')) : {}; - result = compiler.compile({ - type: 'root', - children: toc(input, config).map - }); + result = toc(input, config); - t.is(result, output, 'should work on `' + fixture + '`'); + t.deepEqual(result, output, 'should work on `' + fixture + '`'); }); t.end();