diff options
Diffstat (limited to 'lib/generators')
-rw-r--r-- | lib/generators/ebook.js | 144 | ||||
-rw-r--r-- | lib/generators/website.js | 76 |
2 files changed, 126 insertions, 94 deletions
diff --git a/lib/generators/ebook.js b/lib/generators/ebook.js index e6a33d3..96775b1 100644 --- a/lib/generators/ebook.js +++ b/lib/generators/ebook.js @@ -1,12 +1,13 @@ -var util = require("util"); -var path = require("path"); -var Q = require("q"); -var _ = require("lodash"); -var exec = require("child_process").exec; +var util = require('util'); +var path = require('path'); +var Q = require('q'); +var _ = require('lodash'); +var juice = require('juice'); +var exec = require('child_process').exec; -var fs = require("../utils/fs"); -var stringUtils = require("../utils/string"); -var BaseGenerator = require("./website"); +var fs = require('../utils/fs'); +var stringUtils = require('../utils/string'); +var BaseGenerator = require('./website'); var Generator = function(book, format) { BaseGenerator.apply(this, arguments); @@ -15,10 +16,10 @@ var Generator = function(book, format) { this.ebookFormat = format; // Resources namespace - this.namespace = "ebook"; + this.namespace = 'ebook'; // Styles to use - this.styles = _.compact(["print", "ebook", this.ebookFormat]); + this.styles = _.compact(['print', 'ebook', this.ebookFormat]); // Convert images (svg -> png) this.convertImages = true; @@ -26,9 +27,9 @@ var Generator = function(book, format) { util.inherits(Generator, BaseGenerator); Generator.prototype.prepareTemplates = function() { - this.templates.page = this.book.plugins.template("ebook:page") || path.resolve(this.options.theme, "templates/ebook/page.html"); - this.templates.summary = this.book.plugins.template("ebook:summary") || path.resolve(this.options.theme, "templates/ebook/summary.html"); - this.templates.glossary = this.book.plugins.template("ebook:glossary") || path.resolve(this.options.theme, "templates/ebook/glossary.html"); + this.templates.page = this.book.plugins.template('ebook:page') || path.resolve(this.options.theme, 'templates/ebook/page.html'); + this.templates.summary = this.book.plugins.template('ebook:summary') || path.resolve(this.options.theme, 'templates/ebook/summary.html'); + this.templates.glossary = this.book.plugins.template('ebook:glossary') || path.resolve(this.options.theme, 'templates/ebook/glossary.html'); return Q(); }; @@ -37,8 +38,39 @@ Generator.prototype.prepareTemplates = function() { Generator.prototype.writeSummary = function() { var that = this; - that.book.log.info.ln("write SUMMARY.html"); - return this._writeTemplate(this.templates.summary, {}, path.join(this.options.output, "SUMMARY.html")); + that.book.log.info.ln('write SUMMARY.html'); + return this._writeTemplate(this.templates.summary, {}, path.join(this.options.output, 'SUMMARY.html')); +}; + +// Return template for footer/header with inlined css +Generator.prototype.getPDFTemplate = function(id) { + var tpl = this.options.pdf[id+'Template']; + var defaultTpl = path.resolve(this.options.theme, 'templates/ebook/'+id+'.html'); + var defaultCSS = path.resolve(this.options.theme, 'assets/pdf.css'); + + // Default template from theme + if (!tpl && fs.existsSync(defaultTpl)) { + tpl = fs.readFileSync(defaultTpl, { encoding: 'utf-8' }); + } + + // Inline CSS using juice + var stylesheets = []; + + // From theme + if (fs.existsSync(defaultCSS)) { + stylesheets.push(fs.readFileSync(defaultCSS, { encoding: 'utf-8' })); + } + + // Custom PDF style + if (this.styles.pdf) { + stylesheets.push(fs.readFileSync(this.book.resolve(this.styles.pdf), { encoding: 'utf-8' })); + } + + tpl = juice(tpl, { + extraCss: stylesheets.concat('/n') + }); + + return tpl; }; Generator.prototype.finish = function() { @@ -52,70 +84,70 @@ Generator.prototype.finish = function() { .then(function() { if (!that.ebookFormat) return Q(); - if (!that.options.cover && fs.existsSync(path.join(that.options.output, "cover.jpg"))) { - that.options.cover = path.join(that.options.output, "cover.jpg"); + if (!that.options.cover && fs.existsSync(path.join(that.options.output, 'cover.jpg'))) { + that.options.cover = path.join(that.options.output, 'cover.jpg'); } var d = Q.defer(); var _options = { - "--cover": that.options.cover, - "--title": that.options.title, - "--comments": that.options.description, - "--isbn": that.options.isbn, - "--authors": that.options.author, - "--language": that.options.language, - "--book-producer": "GitBook", - "--publisher": "GitBook", - "--chapter": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter ')]", - "--level1-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-1 ')]", - "--level2-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-2 ')]", - "--level3-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-3 ')]", - "--no-chapters-in-toc": true, - "--max-levels": "1", - "--breadth-first": true + '--cover': that.options.cover, + '--title': that.options.title, + '--comments': that.options.description, + '--isbn': that.options.isbn, + '--authors': that.options.author, + '--language': that.options.language, + '--book-producer': 'GitBook', + '--publisher': 'GitBook', + '--chapter': 'descendant-or-self::*[contains(concat(\' \', normalize-space(@class), \' \'), \' book-chapter \')]', + '--level1-toc': 'descendant-or-self::*[contains(concat(\' \', normalize-space(@class), \' \'), \' book-chapter-1 \')]', + '--level2-toc': 'descendant-or-self::*[contains(concat(\' \', normalize-space(@class), \' \'), \' book-chapter-2 \')]', + '--level3-toc': 'descendant-or-self::*[contains(concat(\' \', normalize-space(@class), \' \'), \' book-chapter-3 \')]', + '--no-chapters-in-toc': true, + '--max-levels': '1', + '--breadth-first': true }; - if (that.ebookFormat == "pdf") { + if (that.ebookFormat == 'pdf') { var pdfOptions = that.options.pdf; _.extend(_options, { - "--chapter-mark": String(pdfOptions.chapterMark), - "--page-breaks-before": String(pdfOptions.pageBreaksBefore), - "--margin-left": String(pdfOptions.margin.left), - "--margin-right": String(pdfOptions.margin.right), - "--margin-top": String(pdfOptions.margin.top), - "--margin-bottom": String(pdfOptions.margin.bottom), - "--pdf-default-font-size": String(pdfOptions.fontSize), - "--pdf-mono-font-size": String(pdfOptions.fontSize), - "--paper-size": String(pdfOptions.paperSize), - "--pdf-page-numbers": Boolean(pdfOptions.pageNumbers), - "--pdf-header-template": String(pdfOptions.headerTemplate) || "<p class='header'><span>"+that.options.title+"</span></p>", - "--pdf-footer-template": String(pdfOptions.footerTemplate) || "<p class='footer'><span>_SECTION_</span> <span style='float:right;'>_PAGENUM_</span></p>" + '--chapter-mark': String(pdfOptions.chapterMark), + '--page-breaks-before': String(pdfOptions.pageBreaksBefore), + '--margin-left': String(pdfOptions.margin.left), + '--margin-right': String(pdfOptions.margin.right), + '--margin-top': String(pdfOptions.margin.top), + '--margin-bottom': String(pdfOptions.margin.bottom), + '--pdf-default-font-size': String(pdfOptions.fontSize), + '--pdf-mono-font-size': String(pdfOptions.fontSize), + '--paper-size': String(pdfOptions.paperSize), + '--pdf-page-numbers': Boolean(pdfOptions.pageNumbers), + '--pdf-header-template': that.getPDFTemplate('header'), + '--pdf-footer-template': that.getPDFTemplate('footer') }); - } else if (that.ebookFormat == "epub") { + } else if (that.ebookFormat == 'epub') { _.extend(_options, { - "--dont-split-on-page-breaks": true + '--dont-split-on-page-breaks': true }); } var command = [ - "ebook-convert", - path.join(that.options.output, "SUMMARY.html"), - path.join(that.options.output, "index."+that.ebookFormat), + 'ebook-convert', + path.join(that.options.output, 'SUMMARY.html'), + path.join(that.options.output, 'index.'+that.ebookFormat), stringUtils.optionsToShellArgs(_options) - ].join(" "); + ].join(' '); - that.book.log.info("start conversion to", that.ebookFormat, "...."); + that.book.log.info('start conversion to', that.ebookFormat, '....'); var child = exec(command, function (error, stdout) { if (error) { that.book.log.info.fail(); if (error.code == 127) { - error.message = "Need to install ebook-convert from Calibre"; + error.message = 'Need to install ebook-convert from Calibre'; } else { - error.message = error.message + " "+stdout; + error.message = error.message + ' '+stdout; } return d.reject(error); } @@ -124,11 +156,11 @@ Generator.prototype.finish = function() { d.resolve(); }); - child.stdout.on("data", function (data) { + child.stdout.on('data', function (data) { that.book.log.debug(data); }); - child.stderr.on("data", function (data) { + child.stderr.on('data', function (data) { that.book.log.debug(data); }); diff --git a/lib/generators/website.js b/lib/generators/website.js index e1a3cce..18ec65d 100644 --- a/lib/generators/website.js +++ b/lib/generators/website.js @@ -1,18 +1,18 @@ -var util = require("util"); -var path = require("path"); -var Q = require("q"); -var _ = require("lodash"); +var util = require('util'); +var path = require('path'); +var Q = require('q'); +var _ = require('lodash'); -var nunjucks = require("nunjucks"); -var AutoEscapeExtension = require("nunjucks-autoescape")(nunjucks); -var FilterExtension = require("nunjucks-filter")(nunjucks); +var nunjucks = require('nunjucks'); +var AutoEscapeExtension = require('nunjucks-autoescape')(nunjucks); +var FilterExtension = require('nunjucks-filter')(nunjucks); -var fs = require("../utils/fs"); -var BaseGenerator = require("../generator"); -var links = require("../utils/links"); -var i18n = require("../utils/i18n"); +var fs = require('../utils/fs'); +var BaseGenerator = require('../generator'); +var links = require('../utils/links'); +var i18n = require('../utils/i18n'); -var pkg = require("../../package.json"); +var pkg = require('../../package.json'); var Generator = function() { BaseGenerator.apply(this, arguments); @@ -21,10 +21,10 @@ var Generator = function() { this.revision = new Date(); // Resources namespace - this.namespace = "website"; + this.namespace = 'website'; // Style to integrates in the output - this.styles = ["website"]; + this.styles = ['website']; // Convert images (svg -> png) this.convertImages = false; @@ -63,9 +63,9 @@ Generator.prototype.prepareStyles = function() { // Prepare templates Generator.prototype.prepareTemplates = function() { - this.templates.page = this.book.plugins.template("site:page") || path.resolve(this.options.theme, "templates/website/page.html"); - this.templates.langs = this.book.plugins.template("site:langs") || path.resolve(this.options.theme, "templates/website/langs.html"); - this.templates.glossary = this.book.plugins.template("site:glossary") || path.resolve(this.options.theme, "templates/website/glossary.html"); + this.templates.page = this.book.plugins.template('site:page') || path.resolve(this.options.theme, 'templates/website/page.html'); + this.templates.langs = this.book.plugins.template('site:langs') || path.resolve(this.options.theme, 'templates/website/langs.html'); + this.templates.glossary = this.book.plugins.template('site:glossary') || path.resolve(this.options.theme, 'templates/website/glossary.html'); return Q(); }; @@ -79,7 +79,7 @@ Generator.prototype.prepareTemplateEngine = function() { var language = that.book.config.normalizeLanguage(); if (!i18n.hasLocale(language)) { - that.book.log.warn.ln("Language '"+language+"' is not available as a layout locales (en, "+i18n.getLocales().join(", ")+")"); + that.book.log.warn.ln('Language "'+language+'" is not available as a layout locales (en, '+i18n.getLocales().join(', ')+')'); } var folders = _.chain(that.templates) @@ -96,14 +96,14 @@ Generator.prototype.prepareTemplateEngine = function() { ); // Add filter - that.env.addFilter("contentLink", that.book.contentLink.bind(that.book)); - that.env.addFilter("lvl", function(lvl) { - return lvl.split(".").length; + that.env.addFilter('contentLink', that.book.contentLink.bind(that.book)); + that.env.addFilter('lvl', function(lvl) { + return lvl.split('.').length; }); // Add extension - that.env.addExtension("AutoEscapeExtension", new AutoEscapeExtension(that.env)); - that.env.addExtension("FilterExtension", new FilterExtension(that.env)); + that.env.addExtension('AutoEscapeExtension', new AutoEscapeExtension(that.env)); + that.env.addExtension('FilterExtension', new FilterExtension(that.env)); }); }; @@ -122,20 +122,20 @@ Generator.prototype.convertFile = function(input) { return that.book.parsePage(input, { convertImages: that.convertImages, interpolateTemplate: function(page) { - return that.callHook("page:before", page); + return that.callHook('page:before', page); }, interpolateContent: function(page) { - return that.callHook("page", page); + return that.callHook('page', page); } }) .then(function(page) { var relativeOutput = that.book.contentPath(page.path); var output = path.join(that.options.output, relativeOutput); - var basePath = path.relative(path.dirname(output), that.options.output) || "."; - if (process.platform === "win32") basePath = basePath.replace(/\\/g, "/"); + var basePath = path.relative(path.dirname(output), that.options.output) || '.'; + if (process.platform === 'win32') basePath = basePath.replace(/\\/g, '/'); - that.book.log.debug.ln("write parsed file", page.path, "to", relativeOutput); + that.book.log.debug.ln('write parsed file', page.path, 'to', relativeOutput); return that._writeTemplate(that.templates.page, { progress: page.progress, @@ -144,7 +144,7 @@ Generator.prototype.convertFile = function(input) { content: page.sections, basePath: basePath, - staticBase: links.join(basePath, "gitbook") + staticBase: links.join(basePath, 'gitbook') }, output); }); }; @@ -155,7 +155,7 @@ Generator.prototype.writeLangsIndex = function() { return this._writeTemplate(this.templates.langs, { langs: this.book.langs - }, path.join(this.options.output, "index.html")); + }, path.join(this.options.output, 'index.html')); }; // Write glossary @@ -163,7 +163,7 @@ Generator.prototype.writeGlossary = function() { // No glossary if (this.book.glossary.length === 0) return Q(); - return this._writeTemplate(this.templates.glossary, {}, path.join(this.options.output, "GLOSSARY.html")); + return this._writeTemplate(this.templates.glossary, {}, path.join(this.options.output, 'GLOSSARY.html')); }; // Convert a page into a normalized data set @@ -180,7 +180,7 @@ Generator.prototype.normalizePage = function(page) { return Q() .then(function() { - return _callHook("page"); + return _callHook('page'); }) .then(function() { return page; @@ -222,10 +222,10 @@ Generator.prototype._writeTemplate = function(tpl, options, output, interpolate) options: that.options, - basePath: ".", - staticBase: path.join(".", "gitbook"), + basePath: '.', + staticBase: path.join('.', 'gitbook'), - "__": that.book.i18n.bind(that.book) + '__': that.book.i18n.bind(that.book) }, options) ); }) @@ -244,15 +244,15 @@ Generator.prototype.copyAssets = function() { // Copy gitbook assets return fs.copy( - path.join(that.options.theme, "assets"), - path.join(that.options.output, "gitbook") + path.join(that.options.theme, 'assets/'+this.namespace), + path.join(that.options.output, 'gitbook') ) // Copy plugins assets .then(function() { return Q.all( _.map(that.book.plugins.list, function(plugin) { - var pluginAssets = path.join(that.options.output, "gitbook/plugins/", plugin.name); + var pluginAssets = path.join(that.options.output, 'gitbook/plugins/', plugin.name); return plugin.copyAssets(pluginAssets, that.namespace); }) ); |