Add init command

This commit is contained in:
Samy Pessé
2016-02-28 14:47:34 +01:00
parent 8cda844ef1
commit 4aa66338fc
7 changed files with 179 additions and 8 deletions
+14 -3
View File
@@ -6,7 +6,6 @@ var location = require('../utils/location');
var error = require('../utils/error');
var BackboneFile = require('./file');
/*
An article represent an entry in the Summary.
It's defined by a title, a reference, and children articles,
@@ -37,8 +36,9 @@ function TOCArticle(def, parent) {
var parts = url.parse(this.ref);
if (!this.isExternal()) {
this.path = parts.pathname;
this.anchor = parts.hash;
var parts = this.ref.split('#');
this.path = (parts.length > 1? parts.slice(0, -1).join('#') : this.ref);
this.anchor = (parts.length > 1? '#' + _.last(parts) : null);
}
}
@@ -264,6 +264,17 @@ Summary.prototype.find = function(filter) {
return result;
};
// Flatten the list of articles
Summary.prototype.flatten = function() {
var result = [];
this.walk(function(article) {
result.push(article);
});
return result;
};
// Return the first TOCArticle for a specific page (or path)
Summary.prototype.getArticle = function(page) {
if (!_.isString(page)) page = page.path;
+9 -2
View File
@@ -13,6 +13,7 @@ var error = require('./utils/error');
var Promise = require('./utils/promise');
var Logger = require('./utils/logger');
var parsers = require('./parsers');
var initBook = require('./init');
/*
@@ -103,10 +104,10 @@ function Book(opts) {
}
});
_.bindAll(this);
// Loop for template filters/blocks
error.deprecateField(this, 'book', this, '"book" property is deprecated, use "this" directly instead');
_.bindAll(this);
}
// Return templating context for the book
@@ -368,5 +369,11 @@ Book.setup = function(fs, root, opts) {
});
};
// Initialize a book
Book.init = function(fs, root, opts) {
return Book.setup(fs, root, opts)
.then(initBook);
};
module.exports = Book;
+12
View File
@@ -7,6 +7,7 @@ var tinylr = require('tiny-lr');
var Promise = require('../utils/promise');
var PluginsManager = require('../plugins');
var Book = require('../book');
var initBook = require('../init');
var helper = require('./helper');
var Server = require('./server');
@@ -14,6 +15,17 @@ var watch = require('./watch');
module.exports = {
commands: [
{
name: 'init [book]',
description: 'setup and create files for chapters',
options: [
helper.options.log
],
exec: function(args) {
var input = path.resolve(args[0] || process.cwd());
return Book.init(helper.nodeFS, input);
}
},
{
name: 'parse [book]',
+68
View File
@@ -0,0 +1,68 @@
var _ = require('lodash');
var path = require('path');
var fs = require('./utils/fs');
var Promise = require('./utils/promise');
// Initialize folder structure for a book
// Read SUMMARY to created the right chapter
function initBook(book) {
var extensionToUse = '.md';
book.log.info.ln('init book at', book.root);
return fs.mkdirp(book.root)
.then(function() {
return book.config.load();
})
.then(function() {
book.log.info.ln('detect structure from SUMMARY (if it exists)');
return book.summary.load();
})
.then(function() {
var summary = book.summary.path || 'SUMMARY.md';
var articles = book.summary.flatten();
// Use extension of summary
extensionToUse = path.extname(summary);
// Readme doesn't have a path
if (!articles[0].path) {
articles[0].path = 'README' + extensionToUse;
}
// Summary doesn't exists? create one
if (!book.summary.path) {
articles.push({
title: 'Summary',
path: 'SUMMARY'+extensionToUse
});
}
// Create files that don't exist
return Promise.serie(articles, function(article) {
if (!article.path) return;
var absolutePath = book.resolve(article.path);
return fs.exists(absolutePath)
.then(function(exists) {
if(exists) {
book.log.info.ln('found', article.path);
return;
} else {
book.log.info.ln('create', article.path);
}
return fs.mkdirp(path.dirname(absolutePath))
.then(function() {
return fs.writeFile(absolutePath, '# '+article.title+'\n\n');
});
});
});
})
.then(function() {
book.log.info.ln('initialization is finished');
});
}
module.exports = initBook;
+3
View File
@@ -25,3 +25,6 @@ require('./assets-inliner');
require('./output-json');
require('./output-website');
require('./output-ebook');
// Misc
require('./init');
+16 -3
View File
@@ -1,18 +1,31 @@
var fs = require('fs');
var path = require('path');
var _ = require('lodash');
var cheerio = require('cheerio');
var should = require('should');
// Assertions to test if an Output has generated a file
should.Assertion.add('file', function(file, description) {
var rootFolder;
if (_.isFunction(this.obj.root)) {
rootFolder = this.obj.root();
} else {
rootFolder = this.obj;
}
this.params = {
actual: this.obj.root(),
actual: rootFolder,
operator: 'have file ' + file,
message: description
};
this.obj.should.have.property('resolve').which.is.a.Function;
this.assert(fs.existsSync(this.obj.resolve(file)));
if (_.isFunction(this.obj.resolve)) {
file = this.obj.resolve(file);
} else {
file = path.resolve(rootFolder, file);
}
this.assert(fs.existsSync(file));
});
should.Assertion.add('html', function(rules, description) {
+57
View File
@@ -0,0 +1,57 @@
var Book = require('../lib/book');
var mock = require('./mock');
describe('Init', function() {
it('should create file according to summary', function() {
return mock.setupFS({
'SUMMARY.md': '# Summary\n\n'
+ '* [Hello](hello.md)\n'
+ '* [Hello 2](hello 2.md)\n'
})
.then(function(rootFolder) {
return Book.init(mock.fs, rootFolder, {
log: function() {}
})
.then(function() {
rootFolder.should.have.file('SUMMARY.md');
rootFolder.should.have.file('README.md');
rootFolder.should.have.file('hello.md');
rootFolder.should.have.file('hello 2.md');
});
})
});
it('should create file subfolder', function() {
return mock.setupFS({
'SUMMARY.md': '# Summary\n\n'
+ '* [Hello](test/hello.md)\n'
+ '* [Hello 2](test/test2/world.md)\n'
})
.then(function(rootFolder) {
return Book.init(mock.fs, rootFolder, {
log: function() {}
})
.then(function() {
rootFolder.should.have.file('README.md');
rootFolder.should.have.file('SUMMARY.md');
rootFolder.should.have.file('test/hello.md');
rootFolder.should.have.file('test/test2/world.md');
});
})
});
it('should create SUMMARY if non-existant', function() {
return mock.setupFS({})
.then(function(rootFolder) {
return Book.init(mock.fs, rootFolder, {
log: function() {}
})
.then(function() {
rootFolder.should.have.file('SUMMARY.md');
rootFolder.should.have.file('README.md');
});
})
});
});