Skip to content

Commit 88ec7cd

Browse files
Merge pull request #181 from uetchy/preserve
add cli flag to prevent doctoc from adding toc to a file without toc. this is good for CI or the combination with [`lint-staged`](https://github.com/okonet/lint-staged). with -p, doctoc will update toc if md has toc sectioon, otherwise doctoc keep it unmodified. I'm not sure `preserve` is the right name for it. so please change it if you have a better one.
2 parents f146558 + f07f3aa commit 88ec7cd

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ You can print to stdout by using the `-s` or `--stdout` option.
140140

141141
[ack]: http://beyondgrep.com/
142142

143+
### Only update existing ToC
144+
145+
Use `--update-only` or `-u` to only update the existing ToC. That is, the Markdown files without ToC will be left untouched. It is good if you want to use `doctoc` with `lint-staged`.
146+
143147
### Usage as a `git` hook
144148

145149
doctoc can be used as a [pre-commit](http://pre-commit.com) hook by using the

doctoc.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@ function cleanPath(path) {
1616
return homeExpanded.replace(/\s/g, '\\ ');
1717
}
1818

19-
function transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut) {
19+
function transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut, updateOnly) {
2020
if (processAll) {
2121
console.log('--all flag is enabled. Including headers before the TOC location.')
2222
}
23+
24+
if (updateOnly) {
25+
console.log('--update-only flag is enabled. Only updating files that already have a TOC.')
26+
}
2327

2428
console.log('\n==================\n');
2529

2630
var transformed = files
2731
.map(function (x) {
2832
var content = fs.readFileSync(x.path, 'utf8')
29-
, result = transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll);
33+
, result = transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, updateOnly);
3034
result.path = x.path;
3135
return result;
3236
});
@@ -58,7 +62,7 @@ function printUsageAndExit(isErr) {
5862

5963
var outputFunc = isErr ? console.error : console.info;
6064

61-
outputFunc('Usage: doctoc [mode] [--entryprefix prefix] [--notitle | --title title] [--maxlevel level] [--all] <path> (where path is some path to a directory (e.g., .) or a file (e.g., README.md))');
65+
outputFunc('Usage: doctoc [mode] [--entryprefix prefix] [--notitle | --title title] [--maxlevel level] [--all] [--update-only] <path> (where path is some path to a directory (e.g., .) or a file (e.g., README.md))');
6266
outputFunc('\nAvailable modes are:');
6367
for (var key in modes) {
6468
outputFunc(' --%s\t%s', key, modes[key]);
@@ -79,7 +83,7 @@ var modes = {
7983
var mode = modes['github'];
8084

8185
var argv = minimist(process.argv.slice(2)
82-
, { boolean: [ 'h', 'help', 'T', 'notitle', 's', 'stdout', 'all' ].concat(Object.keys(modes))
86+
, { boolean: [ 'h', 'help', 'T', 'notitle', 's', 'stdout', 'all' , 'u', 'update-only'].concat(Object.keys(modes))
8387
, string: [ 'title', 't', 'maxlevel', 'm', 'entryprefix' ]
8488
, unknown: function(a) { return (a[0] == '-' ? (console.error('Unknown option(s): ' + a), printUsageAndExit(true)) : true); }
8589
});
@@ -99,6 +103,7 @@ var notitle = argv.T || argv.notitle;
99103
var entryPrefix = argv.entryprefix || '-';
100104
var processAll = argv.all;
101105
var stdOut = argv.s || argv.stdout
106+
var updateOnly = argv.u || argv['update-only']
102107

103108
var maxHeaderLevel = argv.m || argv.maxlevel;
104109
if (maxHeaderLevel && isNaN(maxHeaderLevel) || maxHeaderLevel < 0) { console.error('Max. heading level specified is not a positive number: ' + maxHeaderLevel), printUsageAndExit(true); }
@@ -115,7 +120,7 @@ for (var i = 0; i < argv._.length; i++) {
115120
files = [{ path: target }];
116121
}
117122

118-
transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut);
123+
transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut, updateOnly);
119124

120125
console.log('\nEverything is OK.');
121126
}

lib/transform.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function determineTitle(title, notitle, lines, info) {
106106
return info.hasStart ? lines[info.startIdx + 2] : defaultTitle;
107107
}
108108

109-
exports = module.exports = function transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll) {
109+
exports = module.exports = function transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, updateOnly) {
110110
mode = mode || 'github.com';
111111
entryPrefix = entryPrefix || '-';
112112

@@ -116,6 +116,10 @@ exports = module.exports = function transform(content, mode, maxHeaderLevel, tit
116116
var lines = content.split('\n')
117117
, info = updateSection.parse(lines, matchesStart, matchesEnd)
118118

119+
if (!info.hasStart && updateOnly) {
120+
return { transformed: false };
121+
}
122+
119123
var inferredTitle = determineTitle(title, notitle, lines, info);
120124

121125
var currentToc = info.hasStart && lines.slice(info.startIdx, info.endIdx + 1).join('\n')

0 commit comments

Comments
 (0)