Convert svg images to png in ebook

This commit is contained in:
Samy Pessé
2015-01-28 11:43:44 +01:00
parent 5539ab48a5
commit 324fbb2f69
7 changed files with 140 additions and 7 deletions
+10 -1
View File
@@ -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);
})
+3
View File
@@ -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);
+4
View File
@@ -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
View File
@@ -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
});
+29
View 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
View File
@@ -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
View File
@@ -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",