Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

markdown-toc

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markdown-toc - npm Package Compare versions

Comparing version 0.5.0 to 0.5.1

132

index.js

@@ -10,2 +10,6 @@ /*!

/**
* Module dependencies
*/
var Remarkable = require('remarkable');

@@ -16,21 +20,28 @@ var extend = require('extend-shallow');

/**
* Expose `toc`
* Load `generate` as a remarkable plugin and
* expose the `toc` function.
*
* @param {String} `str` String of markdown
* @param {Object} `options`
* @return {String} Markdown-formatted table of contents
*/
module.exports = toc;
function toc(str, options) {
module.exports = function toc(str, options) {
return new Remarkable()
.use(generate(options))
.render(str);
}
};
/**
* Expose `insert` method
*/
module.exports.insert = require('./lib/insert');
/**
* Generate a markdown table of contents.
* Generate a markdown table of contents. This is the
* function that does all of the main work with Remarkable.
*
* @param {Object} `options`
* @return {String}
* @api private
*/

@@ -43,11 +54,9 @@

md.renderer.render = function (tokens) {
tokens = tokens.slice();
var res = [], i = 0, h = 0;
var len = tokens.length;
var tocstart = -1;
var res = [];
var i = 0;
var h = 0;
while (len--) {
var token = tokens[i++];
if (/<!--[ \t]*toc[ \t]*-->/.test(token.content)) {

@@ -59,15 +68,2 @@ tocstart = token.lines[1];

var lvl = tokens[i].lvl = tokens[i - 1].hLevel;
// Keep the first h1? This is `true` by default
if(opts.firsth1 === false) {
// lvl -= 1;
if (++h === 1) {
continue;
}
}
// if `lvl` is greater than the max depth
if(lvl > opts.maxdepth) {
break;
}
res.push(tokens[i]);

@@ -80,5 +76,3 @@ }

res = res.reduce(function(acc, token) {
if (token.lines[0] > tocstart) {
acc.push(token);
}
if (token.lines[0] > tocstart) { acc.push(token); }
token = linkify(token, opts);

@@ -99,2 +93,38 @@ return acc;

/**
* Render markdown list bullets
*
* @param {Array} `arr` Array of listitem objects
* @param {Object} `opts`
* @return {String}
*/
function bullets(arr, opts) {
var unindent = 0;
// Keep the first h1? This is `true` by default
if(opts && opts.firsth1 === false) {
unindent = 1;
arr.shift();
}
var len = arr.length;
var res = [];
var i = 0;
while (i < len) {
var ele = arr[i++];
ele.lvl -= unindent;
res.push(mdu.listitem(ele.content, ele.lvl, opts));
// break if heading level is greater than maxdepth
if (ele.lvl === opts.maxdepth) {
break;
}
}
return res.join('\n');
}
/**
* Get the highest heading level in the array, so

@@ -105,3 +135,2 @@ * we can un-indent the proper number of levels.

* @return {Number} Highest level
* @api private
*/

@@ -115,2 +144,6 @@

/**
* Turn headings into anchors
*/
function linkify(ele, opts) {

@@ -128,3 +161,12 @@ var slug = slugify(ele.content, opts);

/**
* Slugify links.
*
* @param {String} `str` The string to slugify
* @param {Object} `opts` Pass a custom slugify function on `slugify`
* @return {String}
*/
function slugify(str, opts) {
if (opts && opts.slugify === false) return str;
if (opts && typeof opts.slugify === 'function') {

@@ -136,23 +178,23 @@ return opts.slugify(str, opts);

/**
* Optionally strip specified words from headings.
*
* @param {String} `str`
* @param {String} `opts`
* @return {String}
*/
function strip(str, opts) {
if (opts && typeof opts.strip === 'function') {
opts = opts || {};
if (!opts.strip) return str;
if (typeof opts.strip === 'function') {
return opts.strip(str, opts);
}
var words = opts.strip || [];
var len = words.length;
var i = 0;
while (len--) {
var word = words[i++];
var re = '-*' + word + '-*';
str = str.replace(new RegExp(re), '').trim();
}
return str;
var strip = opts.strip.join('|');
var re = new RegExp(strip, 'g');
return str.trim().replace(re, '')
.replace(/^-|-$/g, '');
}
function bullets(arr, opts) {
return arr.map(function(ele) {
return mdu.listitem(ele.content, ele.lvl, opts);
}).join('\n');
}
'use strict';
var fs = require('fs');
var matter = require('gray-matter');
var toc = require('..');
module.exports = function format(str) {
var re = /(?:<!-- toc(?:stop)? -->)/g;
/**
* The basic idea:
*
* 1. when front-matter exists, we need to avoid turning its properties into headings.
* 2. We need to detect toc markers on the page. For now it's a simple HTML code comment
* to ensure the markdown is compatible with any parser.
*
* @param {String} `str` Pass a string of markdown
* @return {String} Get the same string back with a TOC inserted
*/
var file = matter(str);
var lines = split(file.content, re);
module.exports = function insert(str) {
var re = /(?:<!-- toc(?:\s*stop)? -->)/g;
var file;
if (lines.length === 3) {
lines.splice(2, 0, '<!-- tocstop -->');
lines.splice(1, 0, '<!-- toc -->');
if (/^---/.test(str)) {
file = matter(str);
str = file.content;
}
if (lines.length === 2) {
lines.splice(1, 0, '<!-- toc -->');
var sections = split(str, re);
var last = sections[sections.length - 1];
if (sections.length === 3) {
sections.splice(1, 1, '<!-- toc -->\n\n' + toc(last).content);
sections.splice(2, 0, '<!-- tocstop -->');
}
var res = lines.join('\n\n');
return matter.stringify(res, file.data);
}
if (sections.length === 2) {
sections.splice(1, 0, '<!-- toc -->\n\n' + toc(last).content + '\n\n<!-- tocstop -->');
}
function read(fp) {
return fs.readFileSync(fp, 'utf8');
}
var res = sections.join('\n\n');
if (file) {
return matter.stringify(res, file.data);
}
return res;
};

@@ -37,5 +52,1 @@ function split(str, re) {

}
var str = read('test/expected/insert.md');
var res = format(str);
console.log(res)
{
"name": "markdown-toc",
"description": "Generate a markdown TOC (table of contents).",
"version": "0.5.0",
"description": "Generate a markdown TOC (table of contents) with Remarkable.",
"version": "0.5.1",
"homepage": "https://github.com/jonschlinkert/markdown-toc",

@@ -39,7 +39,19 @@ "author": {

"keywords": [
"anchor",
"commonmark",
"docs",
"document",
"documentation",
"heading",
"markdown",
"md",
"readme",
"markdown",
"remarkable",
"render",
"renderer",
"table of contents",
"table",
"toc",
"table of contents"
"write"
]
}

@@ -1,282 +0,117 @@

# marked-toc [![NPM version](https://badge.fury.io/js/marked-toc.png)](http://badge.fury.io/js/marked-toc)
# markdown-toc [![NPM version](https://badge.fury.io/js/markdown-toc.svg)](http://badge.fury.io/js/markdown-toc)
> Generate a TOC (table of contents) for markdown files
> Generate a markdown TOC (table of contents) with Remarkable.
_(example)_
<!-- toc -->
* [Getting Started](#getting-started)
* [Usage](#usage)
* [Options](#options)
* [template](#template)
* [bullet](#bullet)
* [maxDepth](#maxdepth)
* [firsth1](#firsth1)
* [omit](#omit)
* [clean](#clean)
* [blacklist](#blacklist)
* [allowedChars](#allowedchars)
* [API](#api)
* [toc](#toc)
* [toc.insert](#tocinsert)
* [toc.add](#tocadd)
* [toc.raw](#tocraw)
* [Contributing](#contributing)
* [Author](#author)
* [License](#license)
## Install with [npm](npmjs.org)
<!-- toc stop -->
## Getting Started
Install the module with [npm](npmjs.org):
```bash
npm i -g marked-toc --save
npm i markdown-toc --save
```
In any markdown file, add `<!-- toc -->` where you want to add the TOC. Then in the command line, run:
```bash
toc [filename]
```
If you add the toc to a `README.md`, no need to add `[filename]`, just run `toc`.
## Usage
```javascript
var toc = require('marked-toc');
var file = fs.readFileSync('README.md', 'utf8');
```js
var toc = require('markdown-toc');
// Generate a TOC
toc(file);
toc('# One\n\n# Two').content;
// Results in:
// - [One](#one)
// - [Two](#two)
```
## Options
To allow customization of the output, an object is returned with the following properties:
All methods accept an object of options as the last argument.
- `content` **{String}**: The generated table of contents. Unless you want to customize rendering, this is all you need.
- `highest` **{Number}**: The highest level heading found. This is used to adjust indentation.
- `tokens` **{Array}**: Headings tokens that can be used for custom rendering
### template
Type: `String`
### toc.insert
Default: `<%= depth %><%= bullet %>[<%= heading %>](#<%= url %>)\n`
Insert a table of contents immediately after an _opening_ `<!-- toc -->` code comment, or replace an existing TOC if both an _opening_ comment and a _closing_ comment (`<!-- tocstop -->`) are found. (This strategy works well since code comments in markdown are hidden when viewed as HTML, e.g. on GitHub README's for example).
The Lo-Dash template used to generate the Table of Contents.
**Example**
**Example (this is the default):**
```js
var tmpl = '<%= depth %><%= bullet %>[<%= heading %>](#<%= url %>)\n';
toc(file, {template: tmpl});
```
### bullet
Type: `String|Array`
Default: `* `
The bullet to use for each item in the generated TOC. This is passed as a variable to the `<%= bullet %>` template.
If an array, like `['* ', '- ']`, the bullet point strings will be used based on the header depth.
### maxDepth
Type: `Number`
Default: `3`
Use headings whose depth is at most maxDepth.
### firsth1
Type: `Boolean`
Default: `False`
Include the first h1-level heading in a file. For example, this prevent the first heading in a README from showing up in the TOC.
### omit
Type: `Array`
Default: `['Table of Contents', 'TOC', 'TABLE OF CONTENTS']`
Omit entire headings from the TOC if they have these strings.
### clean
Type: `Array`
Default: `['mixin', 'helper', 'filter']`
Strip "blacklisted" keywords from the headings.
**Example:**
```js
toc(file, {clean: ['docs', 'methods']});
```
converts this:
```markdown
## docs-foo
Foo
<!-- toc -->
- old toc 1
- old toc 2
- old toc 3
<!-- tocstop -->
## methods-bar
Bar
## abc
This is a b c.
## xyz
This is x y z.
```
to:
```markdown
* [foo](#docs-foo)
* [bar](#methods-bar)
Would result in something like:
```
### blacklist
Type: `Boolean`
Default: `true`
An array of strings used the `omit` option:
```js
['grunt', 'helper', 'handlebars-helper', 'mixin', 'filter', 'assemble-contrib', 'assemble']
```
_(These strings are used a lot in documentation headings, but (usually) shouldn't show up in the gererated TOC.)_
### allowedChars
Type: `String`
Default: `-`
String of chars that you want to be whitelisted when headings are "slugified" for links, e.g. `-_~`.
**Example:**
```markdown
// This heading
# Getting Started
<!-- toc -->
- [abc](#abc)
- [xyz](#xyz)
<!-- tocstop -->
// Converts to this link
* [Getting Started](#getting-started)
## abc
This is a b c.
## xyz
This is x y z.
```
## API
## Options
Most methods expect a string as the first paramter, so unless otherwise noted, assume that each example gets the `str` variable from:
### options.bullet
```js
var str = fs.readFileSync('README.md', 'utf8')
```
Type: `String|Array`
### toc
Default: `*`
Generates a Table of Contents from a string.
The bullet to use for each item in the generated TOC. If passed as an array (`['*', '-', '+']`), the bullet point strings will be used based on the header depth.
```js
// Generate a TOC
var table = toc(str);
fs.writeFileSync('toc.md', table);
```
### toc.insert
### options.maxDepth
Inject a TOC at the insertion point in a string, `<!-- toc -->`.
Type: `Number`
**Params:**
Default: `3`
* `str`: the content
* `options`: object of options
Use headings whose depth is at most maxDepth.
```js
toc.insert(str, options);
```
### toc.add
### options.firsth1
1. Read a file and inject a TOC at the specified insertion point, `<!-- toc -->`,
2. Write the file to the specified `dest`, _(or re-write back to the source file if no `dest` is passed)_
Type: `Boolean`
```js
toc.add(src, dest, options)
```
Default: `true`
**Example:**
Exclude the first h1-level heading in a file. For example, this prevents the first heading in a README from showing up in the TOC.
```js
toc.add('path/to/source.md', 'path/to/dest.md');
```
**Source only:**
## Run tests
```js
toc.add('README.md');
```bash
npm test
```
### toc.raw
Output a "raw" (JSON) Table of Contents **object**, for customization and usage in templates
```js
toc.raw(str, options);
```
Returns an object (JSON) with two properties, `data` and `toc`:
* `data`: array of headings and associated properties used to construct a TOC. **TIP**: this can be extended with properties, such as src path etc.
* `toc`: the actual Table of Contents result, as a string
**Example:**
```json
{
// Array of
"data": [
{
"depth": "",
"bullet": "* ",
"heading": "Getting Started",
"url": "getting-started"
},
{
"depth": "",
"bullet": "* ",
"heading": "Usage",
"url": "usage"
}
],
// String. the actual TOC
"toc": "* [Getting Started](#getting-started)\n* [Options](#options)\n* [Contributing](#contributing)\n"
}
```
See [an example](./examples/toc.json).
## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint your code using [jshint](jshint.com) and run tests with `mocha -R spec` before making a pull request.
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/markdown-toc/issues)
## Author
**Jon Schlinkert**
+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright (c) 2014 Jon Schlinkert, contributors
Licensed under the MIT license.
Copyright (c) 2014 Jon Schlinkert
Released under the MIT license
***
_This file was generated by [verb](https://github.com/assemble/verb) on December 21, 2014._
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc