mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 10:03:31 +00:00
Add init command
This commit is contained in:
+14
-3
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
@@ -25,3 +25,6 @@ require('./assets-inliner');
|
||||
require('./output-json');
|
||||
require('./output-website');
|
||||
require('./output-ebook');
|
||||
|
||||
// Misc
|
||||
require('./init');
|
||||
|
||||
+16
-3
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user