Socket
Socket
Sign inDemoInstall

doctoc

Package Overview
Dependencies
2
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.0 to 0.2.0

.travis.yml

154

doctoc.js
#!/usr/bin/env node
var path = require('path'),
fs = require('fs'),
_ = require('underscore'),
file = require('./lib/file'),
argv = process.argv,
file;
'use strict';
var path = require('path')
, fs = require('fs')
, file = require('./lib/file')
, transform = require('./lib/transform')
, argv = process.argv
, files;
function cleanPath(path) {
var homeExpanded = (path.indexOf('~') === 0) ? process.env.HOME + path.substr(1) : path;
var homeExpanded = (path.indexOf('~') === 0) ? process.env.HOME + path.substr(1) : path;
// Escape all spaces
return homeExpanded.replace(/\s/g, '\\ ');
// Escape all spaces
return homeExpanded.replace(/\s/g, '\\ ');
}
function notNull(x) { return x !== null; }
function addLink(header) {
return _(header).extend({
link: '#' + header.name.trim().toLowerCase()
.replace(/ /g,'-')
.replace(/[`.,()*]/g,'')
function transformAndSave(files) {
console.log('\n==================\n');
var transformed = files
.map(function (x) {
var content = fs.readFileSync(x.path, 'utf8')
, result = transform(content);
result.path = x.path;
return result;
});
}
var changed = transformed.filter(function (x) { return x.transformed; })
, unchanged = transformed.filter(function (x) { return !x.transformed; });
function getHashedHeaders (_lines) {
// Find headers of the form '### xxxx xxx xx'
return _lines
.map(function (x, index) {
var match = /^(\#{1,8})[ ]*(.+)$/.exec(x);
return match ? {
rank : match[1].length,
name : match[2],
line : index
} : null;
})
.filter(notNull)
.value();
}
unchanged.forEach(function (x) {
console.log('"%s" is up to date', x.path);
});
function getUnderlinedHeaders (_lines) {
// Find headers of the form
// h1 h2
// == --
return _lines
.map(function (line, index, lines) {
if (index === 0) return null;
var rank;
if (/^==+/.exec(line)) rank = 1;
else if (/^--+/.exec(line)) rank = 2;
else return null;
return {
rank : rank,
name : lines[index - 1],
line : index - 1
};
})
.filter(notNull)
.value();
changed.forEach(function (x) {
console.log('"%s" will be updated', x.path);
fs.writeFileSync(x.path, x.data, 'utf8');
});
}
function transform (f, content) {
var lines = content.split('\n'),
_lines = _(lines).chain(),
allHeaders = getHashedHeaders(_lines).concat(getUnderlinedHeaders(_lines)),
lowestRank = _(allHeaders).chain().pluck('rank').min().value(),
linkedHeaders = _(allHeaders).map(addLink);
if (linkedHeaders.length === 0) return { transformed: false };
var toc =
'**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*' +
'\n\n' +
linkedHeaders.map(function (x) {
var indent = _(_.range(x.rank - lowestRank))
.reduce(function (acc, x) { return acc + '\t'; }, '');
return indent + '- [' + x.name + '](' + x.link + ')';
})
.join('\n') +
'\n';
var currentToc = _lines
.first(linkedHeaders[0].line)
.value()
.join('\n');
if (currentToc === toc) {
console.log('"%s" is up to date', f.path);
return { transformed: false };
}
console.log('"%s" will be updated', f.path);
// Skip all lines up to first header since that is the old table of content
var remainingContent = _lines
.rest(linkedHeaders[0].line)
.value()
.join('\n');
var data = toc + '\n' + remainingContent;
return {
transformed : true,
data : data,
path : f.path
};
}
function transformAndSave(files) {
console.log('\n==================\n');
_(files)
.chain()
.map(function (x) {
var content = fs.readFileSync(x.path, 'utf8');
return transform(x, content);
})
.filter(function (x) { return x.transformed; })
.each(function (x) {
fs.writeFileSync(x.path, x.data, 'utf8');
});
}
if (argv.length !== 3) {
console.log('Usage: doctoc <path> (where path is some path to a directory (i.e. .) or a file (i.e. README.md) )');
process.exit(0);
console.log('Usage: doctoc <path> (where path is some path to a directory (i.e. .) or a file (i.e. README.md) )');
process.exit(0);
}
var target = cleanPath(argv[2]),
stat = fs.statSync(target);
stat = fs.statSync(target);

@@ -140,0 +50,0 @@ if (stat.isDirectory()) {

@@ -1,4 +0,4 @@

var path = require('path'),
fs = require('fs'),
_ = require('underscore');
var path = require('path')
, fs = require('fs')
, _ = require('underscore');

@@ -9,44 +9,44 @@ var markdownExts = ['.md', '.markdown'];

function separateFilesAndDirs(fileInfos) {
return {
directories : _(fileInfos).filter(function (x) {
return x.isDirectory() && !_(ignoredDirs).include(x.name);
}),
markdownFiles : _(fileInfos).filter(function (x) {
return x.isFile() && _(markdownExts).include(path.extname(x.name));
})
};
return {
directories : _(fileInfos).filter(function (x) {
return x.isDirectory() && !_(ignoredDirs).include(x.name);
}),
markdownFiles : _(fileInfos).filter(function (x) {
return x.isFile() && _(markdownExts).include(path.extname(x.name));
})
};
}
function findRec(currentPath) {
function getStat (entry) {
var target = path.join(currentPath, entry),
stat = fs.statSync(target);
function getStat (entry) {
var target = path.join(currentPath, entry),
stat = fs.statSync(target);
return _(stat).extend({
name: entry,
path: target
});
}
function process (fileInfos) {
var res = separateFilesAndDirs(fileInfos);
var tgts = _(res.directories).pluck('path');
return _(stat).extend({
name: entry,
path: target
});
}
function process (fileInfos) {
var res = separateFilesAndDirs(fileInfos);
var tgts = _(res.directories).pluck('path');
if (res.markdownFiles.length > 0)
console.log('\nFound %s in "%s"', _(res.markdownFiles).pluck('name').join(', '), currentPath);
else
console.log('\nFound nothing in "%s"', currentPath);
if (res.markdownFiles.length > 0)
console.log('\nFound %s in "%s"', _(res.markdownFiles).pluck('name').join(', '), currentPath);
else
console.log('\nFound nothing in "%s"', currentPath);
return {
markdownFiles : res.markdownFiles,
subdirs : tgts
};
}
return {
markdownFiles : res.markdownFiles,
subdirs : tgts
};
}
var stats = _(fs.readdirSync(currentPath)).map(getStat),
res = process(stats),
markdownsInSubdirs = _(res.subdirs).map(findRec),
allMarkdownsHereAndSub = res.markdownFiles.concat(markdownsInSubdirs);
var stats = _(fs.readdirSync(currentPath)).map(getStat)
, res = process(stats)
, markdownsInSubdirs = _(res.subdirs).map(findRec)
, allMarkdownsHereAndSub = res.markdownFiles.concat(markdownsInSubdirs);
return _(allMarkdownsHereAndSub).flatten();
return _(allMarkdownsHereAndSub).flatten();
}

@@ -57,3 +57,3 @@

exports.findMarkdownFiles = function(dir) {
return findRec(dir);
return findRec(dir);
};

@@ -60,0 +60,0 @@

@@ -5,3 +5,3 @@ {

"description": "Generates TOC for markdown files of local git repo.",
"version": "0.1.0",
"version": "0.2.0",
"repository": {

@@ -11,2 +11,5 @@ "type": "git",

},
"scripts": {
"test": "node-trap test/{**/*.js,*.js}"
},
"main": "doctoc.js",

@@ -18,6 +21,9 @@ "bin": "doctoc.js",

"dependencies": {
"underscore": ">=1.3.3"
"underscore": ">=1.3.3",
"anchor-markdown-header": "~0.1.1"
},
"devDependencies": {},
"license": "MIT/X11",
"devDependencies": {
"trap": "~0.3.2"
},
"license": "MIT",
"keywords": [

@@ -24,0 +30,0 @@ "github",

@@ -0,11 +1,14 @@

# DocToc [![build status](https://secure.travis-ci.org/thlorenz/doctoc.png)](http://travis-ci.org/thlorenz/doctoc)
Generates table of contents for markdown files inside local git repository. Links are compatible with anchors generated by github
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [DocToc](#doctoc)
- [Installation](#installation)
- [Usage](#usage)
- [Installation](#installation)
- [Usage](#usage)
- [Adding toc to all files in a directory and sub directories](#adding-toc-to-all-files-in-a-directory-and-sub-directories)
- [Adding toc to a single file](#adding-toc-to-a-single-file)
- [Example](#example)
# DocToc
Generates table of contents for markdown files inside local git repository. Links are compatible with anchors generated by github
## Installation

@@ -17,2 +20,4 @@

### Adding toc to all files in a directory and sub directories
Go into the directory that contains you local git project and type:

@@ -26,2 +31,4 @@

### Adding toc to a single file
If you want to convert only a specific file, do:

@@ -31,4 +38,4 @@

Example:
#### Example
doctoc README.md

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc