diff --git a/README.md b/README.md index 0a578fb..b7f8d04 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ by github or other sites via a command line flag. -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + - [Installation](#installation) - [Usage](#usage) @@ -20,6 +20,7 @@ by github or other sites via a command line flag. - [Specifying location of toc](#specifying-location-of-toc) - [Specifying a custom TOC title](#specifying-a-custom-toc-title) - [Specifying a maximum heading level for TOC entries](#specifying-a-maximum-heading-level-for-toc-entries) + - [Specifying the minimum number of headings required for TOC generation](#specifying-the-minimum-number-of-headings-required-for-toc-generation) - [Printing to stdout](#printing-to-stdout) - [Usage as a `git` hook](#usage-as-a-git-hook) @@ -134,6 +135,17 @@ By default, - no limit is placed on Markdown-formatted headings, - whereas headings from embedded HTML are limited to 4 levels. +### Specifying the minimum number of headings required for TOC generation + +Use the `--minheaders` option to limit when a TOC is generated; e.g., `doctoc --minheaders 3 .` + +This allows you to only generate TOCs if there are a minimum number of headings. + +By default, + +- no minimum count is placed on headings +- passing `0` will generate a TOC when any number of headings exist + ### Printing to stdout You can print to stdout by using the `-s` or `--stdout` option. diff --git a/doctoc.js b/doctoc.js index 40cb9a1..57d9103 100755 --- a/doctoc.js +++ b/doctoc.js @@ -16,13 +16,13 @@ function cleanPath(path) { return homeExpanded.replace(/\s/g, '\\ '); } -function transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, stdOut) { +function transformAndSave(files, mode, maxHeaderLevel, minHeadersLevel, title, notitle, entryPrefix, stdOut) { console.log('\n==================\n'); var transformed = files .map(function (x) { var content = fs.readFileSync(x.path, 'utf8') - , result = transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix); + , result = transform(content, mode, maxHeaderLevel, minHeadersLevel, title, notitle, entryPrefix); result.path = x.path; return result; }); @@ -76,7 +76,7 @@ var mode = modes['github']; var argv = minimist(process.argv.slice(2) , { boolean: [ 'h', 'help', 'T', 'notitle', 's', 'stdout'].concat(Object.keys(modes)) - , string: [ 'title', 't', 'maxlevel', 'm', 'entryprefix' ] + , string: [ 'title', 't', 'maxlevel', 'm', 'entryprefix', 'minheaders' ] , unknown: function(a) { return (a[0] == '-' ? (console.error('Unknown option(s): ' + a), printUsageAndExit(true)) : true); } }); @@ -98,6 +98,9 @@ var stdOut = argv.s || argv.stdout var maxHeaderLevel = argv.m || argv.maxlevel; if (maxHeaderLevel && isNaN(maxHeaderLevel) || maxHeaderLevel < 0) { console.error('Max. heading level specified is not a positive number: ' + maxHeaderLevel), printUsageAndExit(true); } +var minHeadersLevel = argv.m || argv.minheaders; +if (minHeadersLevel && isNaN(minHeadersLevel) || minHeadersLevel < 0) { console.error('Min headers level specified is not a positive number: ' + minHeadersLevel), printUsageAndExit(true); } + for (var i = 0; i < argv._.length; i++) { var target = cleanPath(argv._[i]) , stat = fs.statSync(target) @@ -110,7 +113,7 @@ for (var i = 0; i < argv._.length; i++) { files = [{ path: target }]; } - transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, stdOut); + transformAndSave(files, mode, maxHeaderLevel, minHeadersLevel, title, notitle, entryPrefix, stdOut); console.log('\nEverything is OK.'); } diff --git a/lib/transform.js b/lib/transform.js index 8126f11..acd20e7 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -106,13 +106,16 @@ function determineTitle(title, notitle, lines, info) { return info.hasStart ? lines[info.startIdx + 2] : defaultTitle; } -exports = module.exports = function transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix) { +exports = module.exports = function transform(content, mode, maxHeaderLevel, minHeadersLevel, title, notitle, entryPrefix) { mode = mode || 'github.com'; entryPrefix = entryPrefix || '-'; // only limit *HTML* headings by default var maxHeaderLevelHtml = maxHeaderLevel || 4; + // no minimum headers level by default + var minHeadersLevelHtml = minHeadersLevel || 0; + var lines = content.split('\n') , info = updateSection.parse(lines, matchesStart, matchesEnd) @@ -130,9 +133,13 @@ exports = module.exports = function transform(content, mode, maxHeaderLevel, tit var allHeaders = countHeaders(headers) , lowestRank = _(allHeaders).chain().pluck('rank').min().value() - , linkedHeaders = _(allHeaders).map(addAnchor.bind(null, mode)); + , linkedHeaders = _(allHeaders).map(addAnchor.bind(null, mode)) + , noLinkedHeaders = linkedHeaders.length === 0 + , lessHeadersThanMin = linkedHeaders.length < minHeadersLevelHtml; - if (linkedHeaders.length === 0) return { transformed: false }; + if (noLinkedHeaders || lessHeadersThanMin) { + return { transformed: false }; + } // 4 spaces required for proper indention on Bitbucket and GitLab var indentation = (mode === 'bitbucket.org' || mode === 'gitlab.com') ? ' ' : ' ';