mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-17 08:05:19 +00:00
Convert svg images to png in ebook
This commit is contained in:
+10
-1
@@ -456,6 +456,9 @@ Book.prototype.parseGlossary = function() {
|
||||
Book.prototype.parsePage = function(filename, options) {
|
||||
var that = this, page = {};
|
||||
options = _.defaults(options || {}, {
|
||||
// Transform svg images
|
||||
convertImages: false,
|
||||
|
||||
// Interpolate before templating
|
||||
interpolateTemplate: _.identity,
|
||||
|
||||
@@ -514,14 +517,20 @@ Book.prototype.parsePage = function(filename, options) {
|
||||
|
||||
// Prepare html
|
||||
.then(function(_page) {
|
||||
page.sections = pageUtil.normalize(_page.sections, {
|
||||
return pageUtil.normalize(_page.sections, {
|
||||
book: that,
|
||||
convertImages: options.convertImages,
|
||||
input: filename,
|
||||
navigation: that.navigation,
|
||||
base: path.dirname(filename) || './',
|
||||
output: path.dirname(filename) || './',
|
||||
glossary: that.glossary
|
||||
});
|
||||
})
|
||||
|
||||
// Interpolate output
|
||||
.then(function(_sections) {
|
||||
page.sections = _sections;
|
||||
return interpolate(options.interpolateContent);
|
||||
})
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ var Generator = function(book, format) {
|
||||
|
||||
// Styles to use
|
||||
this.styles = _.compact(["ebook", this.ebookFormat]);
|
||||
|
||||
// Convert images (svg -> png)
|
||||
this.convertImages = true;
|
||||
};
|
||||
util.inherits(Generator, BaseGenerator);
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ var Generator = function() {
|
||||
// Style to integrates in the output
|
||||
this.styles = ["website"];
|
||||
|
||||
// Convert images (svg -> png)
|
||||
this.convertImages = false;
|
||||
|
||||
// Templates
|
||||
this.templates = {};
|
||||
};
|
||||
@@ -127,6 +130,7 @@ Generator.prototype.convertFile = function(input) {
|
||||
var that = this;
|
||||
|
||||
return that.book.parsePage(input, {
|
||||
convertImages: that.convertImages,
|
||||
interpolateTemplate: function(page) {
|
||||
return that.callHook("page:before", page);
|
||||
},
|
||||
|
||||
+20
-2
@@ -43,9 +43,27 @@ var fsUtils = {
|
||||
},
|
||||
existsSync: fs.existsSync.bind(fs),
|
||||
readFileSync: fs.readFileSync.bind(fs),
|
||||
clean: cleanFolder
|
||||
clean: cleanFolder,
|
||||
getUniqueFilename: getUniqueFilename
|
||||
}
|
||||
|
||||
// Find a filename available
|
||||
function getUniqueFilename(base) {
|
||||
var ext = path.extname(base);
|
||||
base = path.join(path.dirname(base), path.basename(base, ext));
|
||||
|
||||
var filename = base+ext;
|
||||
|
||||
var i = 0;
|
||||
while (1) {
|
||||
if (!fs.existsSync(filename)) break;
|
||||
filename = base+"_"+i+ext;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return filename;
|
||||
};
|
||||
|
||||
|
||||
// List files in a directory
|
||||
function listFiles(root, options) {
|
||||
@@ -112,7 +130,7 @@ function cleanFolder(root) {
|
||||
var _file = path.join(root, file);
|
||||
|
||||
d.notify({
|
||||
i: i,
|
||||
i: i+1,
|
||||
count: files.length,
|
||||
file: _file
|
||||
});
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
var _ = require("lodash");
|
||||
var Q = require("q");
|
||||
var fs = require("fs");
|
||||
var gm = require("gm");
|
||||
|
||||
|
||||
var convert = function(source, dest, options) {
|
||||
var d = Q.defer();
|
||||
options = _.defaults(options || {}, {
|
||||
resize: null
|
||||
});
|
||||
|
||||
var img = gm(source)
|
||||
.options({
|
||||
imageMagick: true
|
||||
});
|
||||
|
||||
if (options.resize) img = img.resize(options.resize.w, options.resize.h);
|
||||
|
||||
img.noProfile()
|
||||
.write(dest, d.makeNodeResolver());
|
||||
|
||||
return d.promise;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
convert: convert,
|
||||
INVALID: [".svg"]
|
||||
};
|
||||
+72
-3
@@ -1,8 +1,11 @@
|
||||
var Q = require('q');
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var cheerio = require('cheerio');
|
||||
|
||||
var links = require('./links');
|
||||
var imgUtils = require('./images');
|
||||
var fs = require('./fs');
|
||||
|
||||
function replaceText($, el, search, replace, text_only ) {
|
||||
return $(el).each(function(){
|
||||
@@ -61,6 +64,7 @@ function pregQuote( str ) {
|
||||
// Adapt an html snippet to be relative to a base folder
|
||||
function normalizeHtml(src, options) {
|
||||
var $ = cheerio.load(src);
|
||||
var toConvert = [];
|
||||
|
||||
$("img").each(function() {
|
||||
var src = $(this).attr("src");
|
||||
@@ -70,6 +74,31 @@ function normalizeHtml(src, options) {
|
||||
src = links.toAbsolute(src, options.base, options.output);
|
||||
}
|
||||
|
||||
// Convert if needed
|
||||
if (options.convertImages) {
|
||||
var ext = path.extname(src);
|
||||
if (_.contains(imgUtils.INVALID, ext)) {
|
||||
// Replace extension
|
||||
var dest = path.join(path.dirname(src), path.basename(src, ext)+".png");
|
||||
|
||||
// Absolute with input
|
||||
dest = path.resolve(options.book.root, dest);
|
||||
|
||||
// Get a name that doesn't exists
|
||||
dest = fs.getUniqueFilename(dest);
|
||||
|
||||
// Reset as relative to book
|
||||
dest = path.relative(options.book.root, dest);
|
||||
|
||||
options.book.log.debug.ln("detect invalid image (will be converted to png):", src);
|
||||
toConvert.push({
|
||||
source: src,
|
||||
dest: dest
|
||||
});
|
||||
src = dest;
|
||||
}
|
||||
}
|
||||
|
||||
$(this).attr("src", src);
|
||||
});
|
||||
|
||||
@@ -109,13 +138,40 @@ function normalizeHtml(src, options) {
|
||||
});
|
||||
});
|
||||
|
||||
return $.html();
|
||||
return {
|
||||
html: $.html(),
|
||||
images: toConvert
|
||||
};
|
||||
};
|
||||
|
||||
// Convert svg images to png
|
||||
function convertImages(images, options) {
|
||||
return _.reduce(images, function(prev, image) {
|
||||
return prev.then(function() {
|
||||
var imgin = path.resolve(options.book.root, image.source);
|
||||
var imgout = path.resolve(options.book.options.output, image.dest);
|
||||
|
||||
options.book.log.debug("convert image", image.source, "to", image.dest, "...");
|
||||
return imgUtils.convert(imgin, imgout)
|
||||
.then(function() {
|
||||
options.book.log.debug.ok();
|
||||
}, function() {
|
||||
options.book.log.debug.fail();
|
||||
});
|
||||
});
|
||||
}, Q());
|
||||
};
|
||||
|
||||
|
||||
// Adapt page content to be relative to a base folder
|
||||
function normalizePage(sections, options) {
|
||||
options = _.defaults(options || {}, {
|
||||
// Current book
|
||||
book: null,
|
||||
|
||||
// Do we need to convert svg?
|
||||
convertImages: false,
|
||||
|
||||
// Current file path
|
||||
input: ".",
|
||||
|
||||
@@ -132,11 +188,24 @@ function normalizePage(sections, options) {
|
||||
glossary: []
|
||||
});
|
||||
|
||||
return _.map(sections, function(section) {
|
||||
// List of images to convert
|
||||
var toConvert = [];
|
||||
|
||||
sections = _.map(sections, function(section) {
|
||||
if (section.type != "normal") return section;
|
||||
section.content = normalizeHtml(section.content, options);
|
||||
|
||||
var out = normalizeHtml(section.content, options);;
|
||||
|
||||
toConvert = toConvert.concat(out.images);
|
||||
section.content = out.html;
|
||||
return section;
|
||||
});
|
||||
|
||||
return Q()
|
||||
.then(function() {
|
||||
return convertImages(toConvert, options);
|
||||
})
|
||||
.thenResolve(sections);
|
||||
};
|
||||
|
||||
// Extract text from sections
|
||||
|
||||
+2
-1
@@ -27,7 +27,8 @@
|
||||
"tmp": "0.0.24",
|
||||
"crc": "3.2.1",
|
||||
"bash-color": "0.0.3",
|
||||
"URIjs": "1.14.1"
|
||||
"URIjs": "1.14.1",
|
||||
"gm": "1.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.18.2",
|
||||
|
||||
Reference in New Issue
Block a user