diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/book.js | 89 | ||||
-rw-r--r-- | lib/generators/ebook.js | 4 | ||||
-rw-r--r-- | lib/generators/website.js | 2 | ||||
-rw-r--r-- | lib/index.js | 5 | ||||
-rw-r--r-- | lib/template.js | 2 | ||||
-rw-r--r-- | lib/utils/logger.js | 77 |
6 files changed, 127 insertions, 52 deletions
diff --git a/lib/book.js b/lib/book.js index 1f5c5c4..2e0ec19 100644 --- a/lib/book.js +++ b/lib/book.js @@ -1,6 +1,7 @@ var Q = require("q"); var _ = require("lodash"); var path = require("path"); +var util = require("util"); var lunr = require('lunr'); var parsers = require("gitbook-parsers"); var color = require('bash-color'); @@ -10,6 +11,7 @@ var parseNavigation = require("./utils/navigation"); var parseProgress = require("./utils/progress"); var pageUtil = require("./utils/page"); var links = require("./utils/links"); +var logger = require("./utils/logger"); var Configuration = require("./configuration"); var TemplateEngine = require("./template"); @@ -23,11 +25,16 @@ var Book = function(root, context, parent) { config: {}, // Log function - log: console.log.bind(console), + log: function(msg) { + process.stdout.write(msg); + }, // Log level logLevel: Book.LOG_LEVELS.INFO - }) + }); + + // Log + this.log = logger(this.context.log, this.context.logLevel); // Root folder of the book this.root = path.resolve(root); @@ -101,7 +108,7 @@ Book.prototype.parse = function() { var multilingual = false; - that.logDebug("start parsing configuration"); + that.log.debug.ln("start parsing configuration"); return this.config.load() .then(function() { @@ -112,11 +119,11 @@ Book.prototype.parse = function() { return that.parseLangs() .then(function() { multilingual = that.langs.length > 0; - if (multilingual) that.logInfo("Parsing multilingual book, with", that.langs.length, "lanuages"); + if (multilingual) that.log.info.ln("Parsing multilingual book, with", that.langs.length, "lanuages"); // Sub-books that inherit from the current book configuration that.books = _.map(that.langs, function(lang) { - that.logInfo("Preparing language book", lang.lang); + that.log.info.ln("Preparing language book", lang.lang); return new Book( path.join(that.root, lang.path), _.merge({}, that.context, { @@ -165,7 +172,7 @@ Book.prototype.generate = function(generator) { var that = this; that.options.generator = generator || that.options.generator; - that.logInfo("start generation with", that.options.generator, "generator"); + that.log.info.ln("start generation with", that.options.generator, "generator"); return Q() // Clean output folder @@ -197,16 +204,16 @@ Book.prototype.generate = function(generator) { if (!file) return; if (file[file.length -1] == "/") { - that.logDebug("transferring folder", file); + that.log.debug.ln("transferring folder", file); return Q(generator.transferFolder(file)); } else if (_.contains(parsers.extensions, path.extname(file)) && that.navigation[file]) { - that.logDebug("parsing", file); + that.log.debug.ln("parsing", file); return that.parsePage(file) .then(function(content) { return Q(generator.writeParsedFile(content, file)); }); } else { - that.logDebug("transferring file", file); + that.log.debug.ln("transferring file", file); return Q(generator.transferFile(file)); } }) @@ -226,7 +233,7 @@ Book.prototype.generate = function(generator) { return generator.callHook("finish"); }) .then(function() { - that.logInfo("generation is finished"); + that.log.info.ln("generation is finished"); }); }; @@ -274,11 +281,14 @@ Book.prototype.generateFile = function(output, options) { _tmpDir = path.join(_tmpDir, lang); } - book.logInfo("copy ebook to", output); + book.log.info("copy ebook to", output, "..."); return fs.copy( path.join(_tmpDir, "index."+options.ebookFormat), _outputFile - ); + ) + .then(function() { + book.log.info.ok(); + }); }; // Multi-langs book @@ -309,16 +319,18 @@ Book.prototype.parsePlugins = function() { // Load plugins that.plugins = _.map(that.options.plugins, function(plugin) { var plugin = new Plugin(that, plugin.name); + that.log.info("Load plugin", plugin.name, "...."); + if (!plugin.isValid()) { - that.logError("Failed to load plugin", plugin.name); + that.log.info.fail(); failed.push(plugin.name); } else { - that.logInfo("Load plugin", plugin.name); + that.log.info.ok(); } return plugin; }); - that.logDebug("load plugins:", that.plugins.length, "loaded, ", failed.length, "failed"); + that.log.debug.ln("load plugins:", that.plugins.length, "loaded, ", failed.length, "failed"); if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(",")+". Run 'gitbook install' to install plugins from NPM.")); return Q(); }; @@ -327,7 +339,7 @@ Book.prototype.parsePlugins = function() { Book.prototype.parseReadme = function() { var that = this; var structure = that.config.getStructure("readme"); - that.logDebug("start parsing readme:", structure); + that.log.debug.ln("start parsing readme:", structure); return that.findFile(structure) .then(function(readme) { @@ -337,7 +349,7 @@ Book.prototype.parseReadme = function() { that.readmeFile = readme.path; that._defaultsStructure(that.readmeFile); - that.logDebug("readme located at", that.readmeFile); + that.log.debug.ln("readme located at", that.readmeFile); return that.template.renderFile(that.readmeFile) .then(function(content) { return readme.parser.readme(content); @@ -355,7 +367,7 @@ Book.prototype.parseLangs = function() { var that = this; var structure = that.config.getStructure("langs"); - that.logDebug("start parsing languages index:", structure); + that.log.debug.ln("start parsing languages index:", structure); return that.findFile(structure) .then(function(langs) { @@ -364,7 +376,7 @@ Book.prototype.parseLangs = function() { that.langsFile = langs.path; that._defaultsStructure(that.langsFile); - that.logDebug("languages index located at", that.langsFile); + that.log.debug.ln("languages index located at", that.langsFile); return that.template.renderFile(that.langsFile) .then(function(content) { return langs.parser.langs(content); @@ -380,7 +392,7 @@ Book.prototype.parseSummary = function() { var that = this; var structure = that.config.getStructure("summary"); - that.logDebug("start parsing summary:", structure); + that.log.debug.ln("start parsing summary:", structure); return that.findFile(structure) .then(function(summary) { @@ -391,7 +403,7 @@ Book.prototype.parseSummary = function() { that._defaultsStructure(that.summaryFile); that.files = _.without(that.files, that.summaryFile); - that.logDebug("summary located at", that.summaryFile); + that.log.debug.ln("summary located at", that.summaryFile); return that.template.renderFile(that.summaryFile) .then(function(content) { return summary.parser.summary(content, { @@ -411,7 +423,7 @@ Book.prototype.parseGlossary = function() { var that = this; var structure = that.config.getStructure("glossary"); - that.logDebug("start parsing glossary: ", structure); + that.log.debug.ln("start parsing glossary: ", structure); return that.findFile(structure) .then(function(glossary) { @@ -422,7 +434,7 @@ Book.prototype.parseGlossary = function() { that._defaultsStructure(that.glossaryFile); that.files = _.without(that.files, that.glossaryFile); - that.logDebug("glossary located at", that.glossaryFile); + that.log.debug.ln("glossary located at", that.glossaryFile); return that.template.renderFile(that.glossaryFile) .then(function(content) { return glossary.parser.glossary(content); @@ -437,17 +449,17 @@ Book.prototype.parseGlossary = function() { Book.prototype.parsePage = function(filename) { var that = this; - that.logDebug("start parsing file", filename); + that.log.debug.ln("start parsing file", filename); var extension = path.extname(filename); var filetype = parsers.get(extension); if (!filetype) return Q.reject(new Error("Can't parse file: "+filename)); - that.logDebug("render template", filename); + that.log.debug.ln("render template", filename); return that.template.renderFile(filename) .then(function(content) { - that.logDebug("use file parser", filetype.name, "for", filename); + that.log.debug.ln("use file parser", filetype.name, "for", filename); return filetype.parser.page(content); }) .then(function(page) { @@ -562,7 +574,7 @@ Book.prototype.indexPage = function(page) { var nav = this.navigation[page.path]; if (!nav) return; - this.logDebug("index page", page.path); + this.log.debug.ln("index page", page.path); this.searchIndex.add({ url: this.contentLink(page.path), title: nav.title, @@ -581,21 +593,6 @@ Book.prototype._defaultsStructure = function(filename) { that.langsFile = that.langsFile || that.config.getStructure("langs")+extension; } -// Log message -Book.prototype.log = function(level) { - if (level < this.context.logLevel) return; - - var args = Array.prototype.slice.apply(arguments); - var levelKey = _.findKey(Book.LOG_LEVELS, function(v) { return v == args[0]; }); - - args[0] = Book.LOG_COLORS[levelKey](levelKey.toLowerCase()+":"); - this.context.log.apply(null, args); -}; -Book.prototype.logDebug = _.partial(Book.prototype.log, Book.LOG_LEVELS.DEBUG); -Book.prototype.logInfo = _.partial(Book.prototype.log, Book.LOG_LEVELS.INFO); -Book.prototype.logWarn = _.partial(Book.prototype.log, Book.LOG_LEVELS.WARNING); -Book.prototype.logError = _.partial(Book.prototype.log, Book.LOG_LEVELS.ERROR); - // Init and return a book Book.init = function(root) { @@ -616,10 +613,10 @@ Book.init = function(root) { }, []); }; - book.logInfo("init book at", root); + book.log.infoLn("init book at", root); return fs.mkdirp(root) .then(function() { - book.logInfo("detect structure from SUMMARY (if it exists)"); + book.log.infoLn("detect structure from SUMMARY (if it exists)"); return book.parseSummary(); }) .fail(function() { @@ -652,7 +649,7 @@ Book.init = function(root) { return fs.exists(absolutePath) .then(function(exists) { - book.logInfo("create", chapter.path); + book.log.infoLn("create", chapter.path); if(exists) return; return fs.mkdirp(path.dirname(absolutePath)) @@ -663,7 +660,7 @@ Book.init = function(root) { })); }) .then(function() { - book.logInfo("initialization is finished"); + book.log.infoLn("initialization is finished"); }); }; diff --git a/lib/generators/ebook.js b/lib/generators/ebook.js index 88159f3..1bad718 100644 --- a/lib/generators/ebook.js +++ b/lib/generators/ebook.js @@ -31,7 +31,7 @@ Generator.prototype.prepareTemplates = function() { Generator.prototype.writeSummary = function() { var that = this; - that.book.logInfo("write SUMMARY.html"); + that.book.log.info.ln("write SUMMARY.html"); return this._writeTemplate(this.templates["summary"], {}, path.join(this.options.output, "SUMMARY.html")); }; @@ -98,7 +98,7 @@ Generator.prototype.finish = function() { stringUtils.optionsToShellArgs(_options) ].join(" "); - that.book.logInfo("start conversion to", that.ebookFormat); + that.book.log.info.ln("start conversion to", that.ebookFormat); exec(command, function (error, stdout, stderr) { if (error) { if (error.code == 127) { diff --git a/lib/generators/website.js b/lib/generators/website.js index bb2daa1..d0c842f 100644 --- a/lib/generators/website.js +++ b/lib/generators/website.js @@ -132,7 +132,7 @@ Generator.prototype.writeParsedFile = function(page) { var basePath = path.relative(path.dirname(output), this.options.output) || "."; if (process.platform === 'win32') basePath = basePath.replace(/\\/g, '/'); - that.book.logInfo("write parsed file", page.path, "to", relativeOutput); + that.book.log.info.ln("write parsed file", page.path, "to", relativeOutput); return that.normalizePage(page) .then(function() { return that._writeTemplate(that.templates["page"], { diff --git a/lib/index.js b/lib/index.js index f32cea9..febd11a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -9,11 +9,12 @@ var Plugin = require("./plugin"); var Server = require("./utils/server"); var stringUtils = require("./utils/string"); var watch = require("./utils/watch"); +var logger = require("./utils/logger"); var LOG_OPTION = { name: "log", description: "Minimum log level to display", - values: _.chain(Book.LOG_LEVELS).keys().map(stringUtils.toLowerCase).value(), + values: _.chain(logger.LEVELS).keys().map(stringUtils.toLowerCase).value(), defaults: "info" }; @@ -43,7 +44,7 @@ module.exports = { 'config': { 'output': output }, - 'logLevel': Book.LOG_LEVELS[(kwargs.log).toUpperCase()] + 'logLevel': kwargs.log })); return book.parse() diff --git a/lib/template.js b/lib/template.js index b4562b1..47244e4 100644 --- a/lib/template.js +++ b/lib/template.js @@ -23,7 +23,7 @@ var BookLoader = nunjucks.Loader.extend({ .then(function(filepath) { // Is local file if (!filepath) filepath = path.resolve(that.book.root, fileurl); - else that.book.logDebug("resolve from git", fileurl, "to", filepath) + else that.book.log.debug.ln("resolve from git", fileurl, "to", filepath) // Read file from absolute path return fs.readFile(filepath) diff --git a/lib/utils/logger.js b/lib/utils/logger.js new file mode 100644 index 0000000..6be4ea7 --- /dev/null +++ b/lib/utils/logger.js @@ -0,0 +1,77 @@ +var _ = require('lodash'); +var util = require('util'); +var color = require('bash-color'); + +var LEVELS = { + DEBUG: 0, + INFO: 1, + WARNING: 2, + ERROR: 3 +}; + +var COLORS = { + DEBUG: color.purple, + INFO: color.cyan, + WARNING: color.yellow, + ERROR: color.red +}; + +module.exports = function(_write, logLevel) { + var logger = {}; + var lastChar = '\n'; + if (_.isString(logLevel)) logLevel = LEVELS[logLevel.toUpperCase()]; + + // Write a simple message + logger.write = function(msg) { + msg = msg.toString(); + lastChar = _.last(msg); + return _write(msg); + }; + + // Write a line + logger.writeLn = function(msg) { + return this.write((msg || "")+"\n"); + }; + + // Write a message with a certain level + logger.log = function(level) { + if (level < logLevel) return; + + var levelKey = _.findKey(LEVELS, function(v) { return v == level; }); + var args = Array.prototype.slice.apply(arguments, [1]); + var msg = util.format.apply(util, args); + + if (lastChar == '\n') { + msg = COLORS[levelKey](levelKey.toLowerCase()+":")+" "+msg; + } + + return logger.write(msg); + }; + + // Write a OK + logger.ok = function(level) { + return logger.log(level, color.green("OK")+"\n"); + }; + + // Write an "FAIL" + logger.fail = function(level) { + return logger.log(level, color.red("ERROR")+"\n"); + }; + + _.each(LEVELS, function(level, levelKey) { + levelKey = levelKey.toLowerCase(); + + logger[levelKey] = _.partial(logger.log, level); + logger[levelKey].ln = function() { + var args = Array.prototype.slice.apply(arguments); + args.push("\n"); + logger[levelKey].apply(logger, args); + }; + logger[levelKey].ok = _.partial(logger.ok, level); + logger[levelKey].fail = _.partial(logger.fail, level); + }); + + return logger; +}; +module.exports.LEVELS = LEVELS; +module.exports.COLORS = COLORS; |